不幸的是克里斯托夫的解决方案,编写只能在非常有限的情况下。 [编辑:如下面评论我不再记得我对这句话的推理,它可能是错误的:“请注意,这将只在抽象类,首先。”]下一个难点是,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