获取泛型类型的方法

时间:2014-11-24 12:31:07

标签: java reflection

也许以前已经回答过,但我没有在这里找到它。请考虑以下代码行:

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();

1 个答案:

答案 0 :(得分:0)

有时,即使在编译之后,确实可以获得泛型类型信息。理论上,这甚至可以用于泛型方法调用。剧透,这是一个坏主意。出于学术原因,让我们考虑如何做到这一点:

  1. 从方法中检查执行堆栈。
  2. 解压缩调用类。
  3. 找到并解释调用类的类文件并解析其调用方法的字节代码。
  4. 找到调用方法的行。
  5. 模拟 javac 的类型推理机制,找到 javac 可能感染的T相同的类型。
  6. 按照您为T找到的名称加载课程。
  7. 这当然不会很好用,如果在源代码中明确指定了T的类型,它就会被破坏。并且您不希望这样做,因为您的方法调用会突然需要IO。

    你可能想要的是返回:

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

    在这种情况下,您需要用户为您提供所需类型,但您需要以类型安全的方式执行此操作。