Get generic class at compile time

那年仲夏 提交于 2019-12-01 19:46:38

问题


While I know you cannot actually get the type of a generic at runtime because of type erasure, I was wondering if it is possible to get it at compile time.

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???
}

Here the compiler knows the type of the generic of handle and what I want is something so I don't have to change the type of handle and the instanceof check (and the cast) when I decide to change the class (in the code, not at runtime of course).


回答1:


Since generic types are subjected to erasure, you will need to specify the java.lang.Class somewhere in the code. One way is to pass it to a generic method:

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));
    }
}

If you don't know what subclasses of ObjType you're looking for, you will need to add a reifiable Class property to ObjectHandle, similar to how java.util.EnumSet and java.util.EnumMap do it:

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));
}


来源:https://stackoverflow.com/questions/18299444/get-generic-class-at-compile-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!