我創建了一個方法,它將返回一個參數化泛型的類型數組,其中'null'表示仍然存在的參數。我對你的Foo層次結構進行了測試,以及使用類「A」的其他答案中提供的示例。
編輯:在我沒有考慮如何重新排序類型會影響綁定。在新方法中,傳入你想要的參數的超類和基類。當我迭代超類時,我通過比較參數名稱來收集類型參數,這些類型參數是從前一個基類向前映射的。我希望這很清楚。
public <S, B extends S> Class[] findTypeParameters(Class<B> base, Class<S> superClass) {
Class[] actuals = new Class[0];
for (Class clazz = base; !clazz.equals(superClass); clazz = clazz.getSuperclass()) {
if (!(clazz.getGenericSuperclass() instanceof ParameterizedType))
continue;
Type[] types = ((ParameterizedType) clazz.getGenericSuperclass()).getActualTypeArguments();
Class[] nextActuals = new Class[types.length];
for (int i = 0; i < types.length; i++)
if (types[i] instanceof Class)
nextActuals[i] = (Class) types[i];
else
nextActuals[i] = map(clazz.getTypeParameters(), types[i], actuals);
actuals = nextActuals;
}
return actuals;
}
private Class map(Object[] variables, Object variable, Class[] actuals) {
for (int i = 0; i < variables.length && i < actuals.length; i++)
if (variables[i].equals(variable))
return actuals[i];
return null;
}
@Test
public void findsTypeOfSuperclass() throws Exception {
assertThat(findTypeParameters(A4.class, A1.class), arrayContaining(Integer.class, Boolean.class, String.class));
assertThat(findTypeParameters(B4.class, A1.class), arrayContaining(Integer.class, Boolean.class, String.class));
assertThat(findTypeParameters(C2.class, A1.class), arrayContaining(Integer.class, null, null));
assertThat(findTypeParameters(D4.class, A1.class), arrayContaining(Integer.class, null, String.class));
}
class A1<T1, T2, T3> {}
class A2<T3, T2> extends A1<Integer, T2, T3> {}
class A3<T2> extends A2<String, T2> {}
class A4 extends A3<Boolean> {}
class B2<X, T3, Y, T2, Z> extends A1<Integer, T2, T3> {}
class B3<X, T2, Y, Z> extends B2<X, String, Y, T2, Z> {}
class B4<X> extends B3<X, Boolean, X, X> {}
class C2<T2, T3> extends A1<Integer, T2, T3> {}
class D2<T2> extends A1<Integer, T2, String> {}
class D3 extends D2 {}
class D4 extends D3 {}
感謝您的回覆:)。它對我有用。我意識到的一點是,當你改變參數的順序時,你沒有考慮到這種情況,例如'Bar extends Foo'。當你將參數類放在數組中的第一個空位時,在這個例子中,你會得到錯誤的類型。你不是嗎? –
drumkey
2011-06-15 23:55:30