我怎样才能做到这一点呢?

public class GenericClass<T>
{
    public Type getMyType()
    {
        //How do I return the type of T?
    }
}

到目前为止,我所尝试的一切总是返回Object类型,而不是使用的特定类型。


当前回答

泛型在运行时不会具体化。这意味着信息在运行时不存在。

在向Java中添加泛型的同时保持向后兼容性是一项壮举(您可以看到关于它的开创性论文:让未来对过去更加安全:向Java编程语言添加泛型)。

关于这个问题有丰富的文献,有些人对目前的状态不满意,有些人说实际上这是一个诱惑,没有真正的需要。你可以阅读这两个链接,我发现它们很有趣。

其他回答

我使用以下方法:

public class A<T> {

    protected Class<T> clazz;

    public A() {
        this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    public Class<T> getClazz() {
        return clazz;
    }
}

public class B extends A<C> {
   /* ... */
    public void anything() {
       // here I may use getClazz();
    }
}

这是我的解决方案

public class GenericClass<T>
{
    private Class<T> realType;

    public GenericClass() {
        findTypeArguments(getClass());
    }

    private void findTypeArguments(Type t) {
        if (t instanceof ParameterizedType) {
            Type[] typeArgs = ((ParameterizedType) t).getActualTypeArguments();
            realType = (Class<T>) typeArgs[0];
        } else {
            Class c = (Class) t;
            findTypeArguments(c.getGenericSuperclass());
        }
    }

    public Type getMyType()
    {
        // How do I return the type of T? (your question)
        return realType;
    }
}

不管你的类层次结构有多少层, 这个解决方案仍然有效,例如:

public class FirstLevelChild<T> extends GenericClass<T> {

}

public class SecondLevelChild extends FirstLevelChild<String> {

}

在本例中,getMyType() = java.lang.String

正如其他人提到的,只有在特定的情况下通过反思才有可能。

如果你真的需要这个类型,这是常见的(类型安全的)变通模式:

public class GenericClass<T> {

     private final Class<T> type;

     public GenericClass(Class<T> type) {
          this.type = type;
     }

     public Class<T> getMyType() {
         return this.type;
     }
}

你不能。如果向类中添加类型为T的成员变量(甚至不需要初始化它),则可以使用它来恢复类型。

当然,你可以。

出于向后兼容性的考虑,Java在运行时不使用这些信息。但是信息实际上是以元数据的形式呈现的,并且可以通过反射访问(但是它仍然不用于类型检查)。

来自官方API:

http://download.oracle.com/javase/6/docs/api/java/lang/reflect/ParameterizedType.html#getActualTypeArguments%28%29

但是,对于您的场景,我不会使用反射。我个人更倾向于将其用于框架代码。在你的例子中,我只是将类型作为构造函数参数添加。