2013-08-18 1 views
1

Хотя я знаю, что вы не можете получить тип родового во время выполнения из-за стирания стилей, мне было интересно, можно ли его получить во время компиляции.Получите общий класс во время компиляции

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 чека (и отливы), когда я решил изменить класс (в коде, а не во время выполнения, конечно).

+1

но компилятор не знает тип 'obj', так что вы должны использовать' instanceof' в любом случае. –

+0

Это похоже на все, что вам нужно, это сокращение для вашего SubObjType, что вы можете сделать на C с typedef. У Java этого нет. –

+0

Если вам не нужен код в общем случае, и ваша единственная проблема заключается в том, что фактический класс может измениться в коде, я бы просто заменил 'if' на' assert handle instanceof SubObjType'. Или вы действительно хотите, чтобы вызов 'handle.setObj' был пропущен, если и когда фактический тип был изменен в коде? – VGR

ответ

1

Поскольку родовые типы подвергаются стиранию, вам нужно указать 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 вы ищете, вам нужно будет добавить свойство reifiable класса в ObjectHandle, подобно тому, как 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)); 
} 
+0

Хм, вот как бы я это сделал. К сожалению, нет крутой компиляции. Это не отвечает на то, что я искал, но это потому, что, похоже, на это нет ответа. Во всяком случае, спасибо за это. :) – AyCe

 Смежные вопросы

  • Нет связанных вопросов^_^