尽管Java的类型擦除,但获得T.class

我正在尝试将接口绑定到其实现,从配置文件中读取,以便我可以将其提供给我的IoC容器。 这大致是我正在尝试做的事情:

public class PropertyImplementationBinder { // ... public Class getInterfaceClass() { return T.class; // OR Class, note T is not newable } public Class getImplementationClass() { return /* read config file to get implementation class */; } } 

是否有可能获得T.class

您需要将类显式传递给构造函数(并自行存储)。

 private final Class clazz; PropertyImplementationBinder(Class clazz){ this.clazz = clazz; } public Class getInterfaceClass() { return clazz; } 

您可以获取类的generics超类的实际类型参数。 这篇博客文章探讨了这种可能性,包括使用琐碎的匿名内部类的一个不错的小技巧。 直接引用:

事实certificate,虽然JVM不会跟踪generics类实例的实际类型参数,但它会跟踪generics类的子类的实际类型参数。 换句话说,虽然new ArrayList()实际上只是运行时的new ArrayList() ,但是如果类扩展了ArrayList ,那么JVM知道StringList的类型参数的实际类型参数。

与广泛接受的相反,可以避免很少已知的类型擦除,这意味着被叫方确实能够知道在呼叫期间使用了哪些通用参数。

请看一下: 使用TypeTokens检索通用参数

本文还讨论了用户使用该技术的经验。 简而言之,我们最终又回到了……

传统和广泛使用的技术: “在构造函数中传递类类型”

顺便说一句。 来自@Richard Gomes的文章中的示例静态方法getType有两个错误。 它应该是这样的:

 static public Class getType(final Class klass, final int pos) { // obtain anonymous, if any, class for 'this' instance final Type superclass = klass.getGenericSuperclass(); // test if an anonymous class was employed during the call if ( !(superclass instanceof ParameterizedType) ) { throw new RuntimeException("This instance should belong to an anonymous class"); } // obtain RTTI of all generic parameters final Type[] types = ((ParameterizedType) superclass).getActualTypeArguments(); // test if enough generic parameters were passed if ( pos >= types.length ) { throw new RuntimeException(String.format("Could not find generic parameter #%d because only %d parameters were passed", pos, types.length)); } if (!(types[pos] instanceof Class)) { throw new RuntimeException("Generic type is not a class but declaration definition(all you get is \"[T]\") " + types[pos]); } // return the type descriptor of the requested generic parameter return (Class) types[pos]; } 

不幸的是,它仍然不是神奇的子弹,因为如果您明确地使用代码,它就会起作用

 getType(new SomeObject(){}.class, 0) // you get String.class 

但如果你这样称呼

 getType(new SomeObject(){}.class, 0) // you get T as TypeVariable and not actuall class of it 

只是命名T.

不,这是不可能的。

Java类型擦除的唯一例外是通过reflection,您可以通过类的字段上的reflection找出参数化类型。