在编译时获得泛型类 [英] Get generic class at compile time

查看:97
本文介绍了在编译时获得泛型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然我知道你不能在运行时因类型擦除而获得泛型类型,但我想知道是否可以在编译时得到它。

  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 = [返回ObjType的方法];
if(obj instanceof [handle的泛型类,这里是SubObjType]){
handle.setObj(obj); // 投???
}

这里编译器知道的通用类型,处理和我想要的是什么,所以我不必改变 handle instanceof check(和cast)当我决定改变类时(在代码中,而不是在运行时)。

解决方案 div>

由于泛型类型会被擦除,所以您需要在代码中的某个地方指定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));






$ b如果你不知道ObjType的子类是什么你需要为ObjectHandle添加一个可重用的Class属性,类似于java.util.EnumSet和java.util.EnumMap这样做:

  class ObjectHandle< T extends ObjType> {

T obj;

private final Class< T>对象类;

ObjectHandle(Class< T> cls){
objectClass = Objects.requireNonNull(cls);
}

Class< T> getObjectClass(){
返回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));
}


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).

解决方案

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

这篇关于在编译时获得泛型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆