2015-01-13 139 views
0

在Java項目中,我定義泛型類掃描.class文件或JAR文件,以反映

public class Test<T> 

和子類

public class SubClass extends Test<Person> 

我的問題是如何掃描代碼,找出哪些類是從Test繼承而來的,類型爲T.我知道,類型T將在運行時被擦除。

,我們可以在.NET中(如下面的代碼)做的任何方法?

public static void RegisterVadas(Container container, params Assembly[] assemblies) 
     { 
      assemblies = assemblies.Distinct().ToArray(); 
      foreach (var assembly in assemblies) 
      { 
       foreach (var vada in assembly.GetTypes() 
       .Where(t => t.IsOrHasGenericInterfaceTypeOf(typeof(IVada<>)))) 
       { 
        RegisterVada(container, vada); 
       } 
      } 
     } 
+1

這是不可能的。類只有在被請求時才被加載,並不是每次都可用。字節碼不檢查泛型類型,所以T被解析爲Object,泛型變量始終爲Object類型,以獲取泛型變量的內容在它們的值上使用'.getClass()'。 –

+0

@PeterRader他沒有詢問任何類型變量,而是關於具有該類型變量的具體類的特定子類,並且該信息被記錄在類文件中。 –

回答

0

首先,你想要什麼來實現這個?

有一些解決方案,例如使用Guava's classpath scanner;然後你可以從類中找到它的父類是什麼類型參數。

+0

我想找出所有在測試繼承的運行時類型和T類型,所以我可以做其他事情。同時,這對調試模型沒有用,因爲調試不能生成jar文件? – user3231931

+0

你告訴我*你想如何實現_something_;它有助於知道*爲什麼*;有時會出現[XY問題] * http://mywiki.wooledge.org/XyProblem)。 –

0

您可以通過反射得到泛型類型的信息:

ParameterizedType superType = (ParameterizedType) SubClass.class.getGenericSuperclass(); 

的方法,您可以通過索引來訪問類型參數。 Test只有一個類型參數,所以index == 0在你的情況。

/** Get the actual type argument used for a single generic placeholder */ 
    public <T> Class<T> getGenericType(int index) { 
     Object typeArg = superType.getActualTypeArguments()[ index ]; 
     if(typeArg instanceof Class) { 
      @SuppressWarnings(JavacWarnings.UNCHECKED) 
      Class<T> result = (Class<T>) typeArg; 
      return result; 
     } 

     if(typeArg instanceof ParameterizedType) { 
      ParameterizedType pt = (ParameterizedType) typeArg; 
      @SuppressWarnings(JavacWarnings.UNCHECKED) 
      Class<T> result = (Class<T>) pt.getRawType(); 
      return result; 
     } 

     throw new RuntimeException("Unsupported type: " + typeArg.getClass()); 
    } 
+0

聽起來很響。謝謝。 – user3231931