在编译时获取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)); }