我有一个泛型类:
class Foo<T> {
protected boolean validateType(Object obj){
if (obj instanceof T) {
return true;
}
return false;
}
}
测试:
Foo foo = new Foo<String>();
foo.validateType(new String()); // should return true
foo.validateType(new Long()); // should return false;
并且有一个函数需要针对泛型类型'T'验证对象,显然上面的代码有错误?
我该怎么做?
答案 0 :(得分:2)
您正在尝试做的事情是不可能的 - 泛型是由erasure在Java中实现的,这意味着泛型参数在运行时不存在。它是编译器进行类型检查的,但在运行时无法区分Foo<String>
和Foo<Long>
之间的区别。
因此,如果您想要检查特定令牌,则必须自己执行此操作。执行此类检查的常见模式是使用Class
对象,其好处是编译器可以对这些对象进行类型检查:
class Foo<T> {
private final Class<T> genericClass;
public Foo(Class<T> clazz) {
this.genericClass = clazz;
}
protected boolean validateType(Object obj){
return genericClass.isInstance(obj);
}
}
请注意,您的来电者现在需要自己传递Class
个对象;没有办法解决这个问题,它本身不能自动连接到它。
(另外,使用if (x) return true; else return false;
与return x;
完全相同但更容易混淆且容易出错时,这是个坏主意。)
答案 1 :(得分:1)
因此Foo
的实例没有关于T
在运行时的信息。
因此,您必须将Class<T>
传递给Foo
的构造函数。
private final Class<T> cl;
protected boolean validateType(Object ob){
return cl.isInstance(ob);
}
...