2013-04-17 69 views
6

Hello all :)我試圖在類中選擇正確的構造函數。下面是代碼:在運行時檢查一個類是否具有使用泛型的特定構造函數

Constructor[] constructors = targetClass.getConstructors(); 
Constructor goodConstructor = null; 
for (Constructor constructor : constructors) { 
    Class[] parameterTypes = constructor.getParameterTypes(); 
    if (parameterTypes.length = 1 && parameterTypes[0].equals(Map.class)) {//here 
     goodConstructor = constructor; 
    } 
} 

我想改用從Map.classMap<String, String>.class。我依稀記得,泛型只適用於編譯時間,所以這就是編譯器抱怨的原因。我如何在運行時檢查該類是否具有正確的構造函數?

問候

回答

8

你想用getGenericParameterTypes()代替:

public class FindConstructor { 

    public static void main(String[] args) throws IOException { 
     for (Constructor<?> constructor : MyClass.class.getConstructors()) { 
      Type[] parameterTypes = constructor.getGenericParameterTypes(); 
      if (parameterTypes.length == 1 && parameterTypes[0] instanceof ParameterizedType) { 
       ParameterizedType parameterizedArg = (ParameterizedType) parameterTypes[0]; 
       if (parameterizedArg.getRawType() != Map.class) { 
        continue; 
       } 

       if (parameterizedArg.getActualTypeArguments()[0] != String.class) { 
        continue; 
       } 

       if (parameterizedArg.getActualTypeArguments()[1] != String.class) { 
        continue; 
       } 
      } 
      System.out.println("found constructor " + constructor); 
     } 
    } 
} 

class MyClass { 
    public MyClass(Map<String, String> map) { 
    } 
} 

現在,如果你改變MyClass()採取Map<String, Integer>它將不再匹配。

使用番石榴的TypeToken這會變得更容易,它利用匿名類來創建我們可以比較的參數化的Type

Type mapStringString = new TypeToken<Map<String, String>>(){}.getType(); 
for (Constructor<?> constructor : MyClass.class.getConstructors()) { 
    Type[] parameterTypes = constructor.getGenericParameterTypes(); 
    if (parameterTypes.length == 1 && parameterTypes[0].equals(mapStringString)) { 
     System.out.println("found constructor " + constructor); 
    } 
} 
+0

刪除我的答案;在回答庫存「泛型使用類型擦除」答案之前,我應該更加小心!我會說,如果你這樣做,那麼幾乎可以肯定你的設計出了問題! :) – James

0

類在java中不能這樣工作。類不能在運行時參數化;只有實例。只有一個Map.class,而不是像你似乎已經假設的那樣爲Map的每個通用實現分配一個類。下面的代碼可能有助於澄清這一點:

Map<String,String> m1 = new HashMap<>(); 
    Map<Object,Long> m2 = new HashMap<>(); 

    System.out.println(m1.getClass() == m2.getClass());//prints "true" 
+0

雖然'Class'的確如此,但Java確實支持表示具有類型參數的類型,即'ParameterizedType'(請參閱我的答案)。類型參數經常編譯(任何時候你聲明通用字段或參數,對於初學者)。如果該信息在類文件中不可用,則無法針對使用泛型的類進行編譯。 –

相關問題