2015-04-19 2 views
1

Есть ли способ, чтобы получить общий вид следующего класса во время выполнения (я буду называть doSomething() во время выполнения):Generic типа класса

class MyClass<D> extends BaseClass<List<D>> { 

    public Class<D> getGenericClass(){ 
     Type [] ta = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments(); 
     Class ty = (Class) ta[0]; // is java.util.List<D> and throws a cast exception 

     // TODO I want to know what kind of class "D" is 
    } 

} 

class BaseClass<T> 
    T data; 
} 

Я хотел бы использовать MyClass следующим образом:

MyClass<Foo> instance = new MyClass<Foo>(); 
Class<Foo> foo = instance.getGenericClass(); 

Строки кода сверху только для того, чтобы показать вам (упрощенный) сценарий, с которым я столкнулся. Если бы я мог создать экземпляр вручную, я бы уже знал, что я использую Foo как общий параметр, но это не так.

FYI Я пытаюсь иметь дело с Android Parcelable и получить правильный загрузчик классов для readParcelable() с помощью дженериков. Бетон: MyClass implements Parcelable. При чтении Parcel я должен указать загрузчик классов, как этот data = parcel.readArrayList(Foo.class.getClassLoader), и я хочу, чтобы определить, что динамически с помощью отражения как data = parcel.readArrayList(getGenericClass().getClassLoader())

Есть ли способ, чтобы получить такую ​​информацию?

Обычно вы бы просто использовать:

Class type = (Class) (getClass().getGenericSuperclass()).getActualTypeArguments()[0]); 

но возвращает java.util.List<D>, но я заинтересован в том, что <D> есть. Есть ли способ погрузиться в этот общий тип?

+0

спасибо, но я с 'GetClass() getGenericSuperclass()) getActualTypeArguments();' я 'java.util.List ' вместо 'java.util.List '. Итак, есть способ получить оценку ''? – sockeqwe

+1

У вас действительно есть несколько 'ClassLoader' в вашем приложении? Я не видел случая, когда тип 'класса', используемый для извлечения« ClassLoader », имел значение« Parcelable ». Можете ли вы объяснить свою ситуацию немного больше? –

+0

Good Point, имеет значение, если 'MyClass' является частью' .aar' упакованной библиотеки? – sockeqwe

ответ

-1

Вы можете попробовать что-то вроде (класс от java.lang.reflect):

ParameterizedType pt = (ParameterizedType)MyClass.class.getGenericSuperclass(); 
Type[] t = pt.getActualTypeArguments(); 

t будет содержать каждый общий тип вашего класса.

EDIT: если это список, вы можете достичь тип списка, используя что-то вроде:..

ParameterizedType listType = (ParameterizedType) listField.getGenericType(); 
Class<?> listClass = (Class<?>) listType.getActualTypeArguments()[0]; 
+0

Что такое 'SubBar'? – sockeqwe

+1

Это работает, если у вас есть переменная или сигнатура метода с определенным фактическим типом (например, «Список »). Он также может работать в случае иерархии классов, где суперкласс или интерфейс определяет общий, и фактическая реализация обеспечивает конкретное значение для этого общего (в отличие от того, что оно все еще является общим для потребителей). Это использование, похоже, не попадает ни в одну из этих категорий. –

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