不幸的是克里斯托夫的解決方案,編寫只能在非常有限的情況下。 [編輯:如下面評論我不再記得我對這句話的推理,它可能是錯誤的:「請注意,這將只在抽象類,首先。」]下一個難點是,g()
只適用於DIRECT子類A
。我們可以修復,但:
private Class<?> extractClassFromType(Type t) throws ClassCastException {
if (t instanceof Class<?>) {
return (Class<?>)t;
}
return (Class<?>)((ParameterizedType)t).getRawType();
}
public Class<B> g() throws ClassCastException {
Class<?> superClass = getClass(); // initial value
Type superType;
do {
superType = superClass.getGenericSuperclass();
superClass = extractClassFromType(superType);
} while (! (superClass.equals(A.class)));
Type actualArg = ((ParameterizedType)superType).getActualTypeArguments()[0];
return (Class<B>)extractClassFromType(actualArg);
}
這將在許多情況下在實踐中,但不是所有的時間。試想一下:
public class Foo<U,T extends Collection<?>> extends A<T> {}
(new Foo<String,List<Object>>() {}).g();
,這將拋出一個ClassCastException
,因爲類型參數在這裏不是Class
或ParameterizedType
在所有;這是TypeVariable
T
。所以現在你會被卡住,試圖找出什麼類型的T
應該代表,等等。
我認爲唯一合理的一般答案類似於Nicolas的初始答案 - 一般來說,如果您的類需要在編譯時實例化某些其他未知類的對象,那麼您的類的用戶需要通過該類的字面量(或者,也許是一個工廠)顯式地給你的類,而不是完全依賴於泛型。
它確實很醜,但帶保護構造函數的技巧對我來說已經足夠了。我使用泛型類作爲抽象類,用作基礎5到10個具體類。謝謝! – 2008-10-08 13:36:16
是否可以使用它來確定對象是什麼泛型?例如 `if(obj.getClazz()是一個字符串)doThis();如果(obj.getClazz()是一個整數)doThat(); ' – dwjohnston 2012-11-09 00:09:36
^解決方案: `if(obj.getClazz()。equals(String.class))...' – dwjohnston 2012-11-09 01:14:32