2014-11-24 60 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) { ... } 

在这种情况下,你需要将用户与所需的类型提供你,但你在一个类型安全的方式做到这一点。