2014-11-24 63 views
1

也許這已經回答過,但我沒有在這裏找到它。考慮下面的代碼行:獲取方法的通用類型

public static <T> T getAs() { ... } 

,能夠獲得對象Class<T>,通過反射?

爲了澄清,我不是找一般類型的一類,就像在

class Foo<T> { 
    public T get() { ...} 
} 

這可以用C#來完成它實在是太好用,例如

class Foo { 
    private List<A> items; 

    public <T extends A> T first() { 
     Class<T> clazz = //Magic?? 
     foreach (A a : items) { 
      if (clazz.isInstance(a)) return (T)a; 
     } 
     return null; 
    } 

} 

像這樣來使用:

SubClass s = fooInst.<SubClass>first(); 
+0

你走低谷http://stackoverflow.com/questions/3403909/get-generic-type-of-class-at-runtime? – reto 2014-11-24 12:34:45

+0

看看這一個,以及:https://docs.oracle.com/javase/tutorial/reflect/member/methodType.html – 2014-11-24 12:35:30

+0

我不認爲這是重複的,我認爲她真的想要類而不是當前類 – 2014-11-24 12:35:58

回答

0

有時候,即使在編譯之後,確實有可能獲得泛型類型信息。理論上,這對於泛型方法調用甚至是可能的。擾流板,這是一個壞主意。由於學術原因,讓我們考慮如何做到這一點:

  1. 從方法中檢查執行堆棧。
  2. 提取調用類。
  3. 找到並解釋調用類的類文件並解析其調用方法的字節碼。
  4. 找到調用方法的行。
  5. 仿真javac的類型推理機制,並找到T相同的類型javac會產生。
  6. 按照您找到的名稱加載課程T

這當然不能很好地工作,如果在源代碼中明確指定了T的類型,它將被破壞。你不想這樣做,因爲你的方法調用會突然需要IO。

你可能想要的是返回:

<T> T getAs(Class<? extends T> type) { ... } 

在這種情況下,你需要將用戶與所需的類型提供你,但你在一個類型安全的方式做到這一點。