根据泛型“T”类型验证对象实例类型

时间:2012-06-29 09:22:13

标签: java

我有一个泛型类:

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'验证对象,显然上面的代码有错误?

我该怎么做?

2 个答案:

答案 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);
}
...