在编译时获取generics类

虽然我知道你因为类型擦除而无法在运行时获得generics的类型,但我想知道是否有可能在编译时获取它。

class ObjectHandle { T obj; void setObj(T o) { obj = o; } } class ObjType {} class SubObjType extends ObjType {} ... ObjectHandle handle = new ObjectHandle(); ... ObjType obj = [method that returns an ObjType]; if(obj instanceof [handle's generic class, here SubObjType]) { handle.setObj(obj); // cast??? } 

这里编译器知道handle的generics的类型和我想要的是什么,所以当我决定更改类时,我不必更改handle的类型和instanceof检查(和强制转换)(在代码中,当然不是在运行时)。

由于generics类型需要擦除,因此您需要在代码中的某处指定java.lang.Class。 一种方法是将其传递给generics方法:

 ObjType obj = /*...*/; handleObj(obj, SubObjType.class); // ... private  void handleObj(ObjType obj, ObjectHandle handle, Class handleableObjClass) { if (handleableObjClass.isInstance(obj)) { handle.setObj(handleableObjClass.cast(obj)); } } 

如果您不知道要查找的ObjType的子类,则需要向ObjectHandle添加可重新获取的Class属性,类似于java.util.EnumSet和java.util.EnumMap的执行方式:

 class ObjectHandle { T obj; private final Class objectClass; ObjectHandle(Class cls) { objectClass = Objects.requireNonNull(cls); } Class getObjectClass() { return objectClass; } void setObj(T o) { obj = o; } } // ... ObjectHandle handle = new ObjectHandle(); // ... ObjectType obj = /*...*/; if (handle.getObjectClass().isInstance(obj)) { handle.setObj(handle.getObjectClass().cast(obj)); }