【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
我有一个泛型类Foo<T>
。 在Foo
的方法中,我想获取类型T的类实例,但是我无法调用T.class
。
使用T.class
绕过它的首选方法是什么?
#1楼
我在抽象的泛型类中遇到了这个问题。 在这种情况下,解决方案更简单:
abstract class Foo<T> {
abstract Class<T> getTClass();
//...
}
然后在派生类上:
class Bar extends Foo<Whatever> {
@Override
Class<T> getTClass() {
return Whatever.class;
}
}
#2楼
这是可能的:
class Foo<T> {
Class<T> clazz = (Class<T>) DAOUtil.getTypeArguments(Foo.class, this.getClass()).get(0);
}
您需要svn / trunk / dao / src / main / java / com / googlecode / genericdao / dao / DAOUtil.java中的两个函数 。
有关更多说明,请参见反映泛型 。
#3楼
假设您有一个通用的抽象超类:
public abstract class Foo<? extends T> {}
然后是第二个类,它使用扩展T的通用Bar扩展了Foo:
public class Second extends Foo<Bar> {}
您可以获取类Bar.class
通过选择在Foo类Type
(从BERT bruynooghe答案),并使用infering它Class
的实例:
Type mySuperclass = myFoo.getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
//Parse it as String
String className = tType.toString().split(" ")[1];
Class clazz = Class.forName(className);
您必须注意,此操作并不理想,因此最好缓存计算的值,以避免对此进行多次计算。 典型用途之一是在通用DAO实现中。
最终实现:
public abstract class Foo<T> {
private Class<T> inferedClass;
public Class<T> getGenericClass(){
if(inferedClass == null){
Type mySuperclass = getClass().getGenericSuperclass();
Type tType = ((ParameterizedType)mySuperclass).getActualTypeArguments()[0];
String className = tType.toString().split(" ")[1];
inferedClass = Class.forName(className);
}
return inferedClass;
}
}
从其他函数的Foo类或Bar类调用时,返回的值为Bar.class。
#4楼
public <T> T yourMethodSignature(Class<T> type) {
// get some object and check the type match the given type
Object result = ...
if (type.isAssignableFrom(result.getClass())) {
return (T)result;
} else {
// handle the error
}
}
#5楼
这是一个可行的解决方案:
@SuppressWarnings("unchecked")
private Class<T> getGenericTypeClass() {
try {
String className = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].getTypeName();
Class<?> clazz = Class.forName(className);
return (Class<T>) clazz;
} catch (Exception e) {
throw new IllegalStateException("Class is not parametrized with generic type!!! Please use extends <> ");
}
}
注意: 只能用作超类
- 必须使用类型化类扩展(
Child extends Generic<Integer>
类Child extends Generic<Integer>
)
要么
- 必须创建为匿名实现(
new Generic<Integer>() {};
)
来源:oschina
链接:https://my.oschina.net/stackoom/blog/3147833