虽然我知道你因为类型擦除而无法在运行时获得泛型类型,但我想知道是否可以在编译时获取它。
class ObjectHandle<T extends ObjType> {
T obj;
void setObj(T o) {
obj = o;
}
}
class ObjType {}
class SubObjType extends ObjType {}
...
ObjectHandle<SubObjType> handle = new ObjectHandle<SubObjType>();
...
ObjType obj = [method that returns an ObjType];
if(obj instanceof [handle's generic class, here SubObjType]) {
handle.setObj(obj); // cast???
}
这里编译器知道handle
的泛型的类型,我想要的是什么,所以我不必更改handle
和instanceof
检查的类型(和当我决定改变类时(在代码中,当然不是在运行时)。
答案 0 :(得分:2)
由于泛型类型需要擦除,因此您需要在代码中的某处指定java.lang.Class。一种方法是将其传递给通用方法:
ObjType obj = /*...*/;
handleObj(obj, SubObjType.class);
// ...
private <T extends ObjType> void handleObj(ObjType obj,
ObjectHandle<T> handle,
Class<T> handleableObjClass) {
if (handleableObjClass.isInstance(obj)) {
handle.setObj(handleableObjClass.cast(obj));
}
}
如果您不知道要查找的ObjType的子类,则需要向ObjectHandle添加可重新生成的Class属性,类似于java.util.EnumSet和java.util.EnumMap的操作方式:
class ObjectHandle<T extends ObjType> {
T obj;
private final Class<T> objectClass;
ObjectHandle(Class<T> cls) {
objectClass = Objects.requireNonNull(cls);
}
Class<T> getObjectClass() {
return objectClass;
}
void setObj(T o) {
obj = o;
}
}
// ...
ObjectHandle<SubObjType> handle = new ObjectHandle<SubObjType>();
// ...
ObjectType obj = /*...*/;
if (handle.getObjectClass().isInstance(obj)) {
handle.setObj(handle.getObjectClass().cast(obj));
}