Java泛型类型比较

时间:2016-01-05 18:01:51

标签: java c++ generics

我想知道Java中是否有类似的东西(C ++和Java混合)

template<typename T> bool compare(Wrapper wrapper) {
    if(wrapper.obj.getClass().equals(T.class))
        return true
    return false
}

为了澄清,该函数接受一个包含java.lang.object的对象,但是我希望能够将该包装器传递给这个通用比较函数来检查该对象是否属于特定类型,即

if(compare<String>(myWrapper))
    // do x

2 个答案:

答案 0 :(得分:2)

不,由于erasure,这是不可能的。基本上,public void RegisterClickEvent(Action<object, EventArgs> method) { Click += new EventHandler<EventArgs>(method); } 方法不知道compare是什么。只有一个T方法(与C ++相反,每个compare只有一个),并且没有给出任何关于它是如何被调用的信息(即,调用者认为它的{{1}要成为。)

典型的解决方案是让类(或方法)接受T,然后使用T

Class<T> cls

当然,这意味着调用站点需要拥有cls.isInstance对象。如果该调用站点本身是一个通用方法,则需要从其调用者获取该引用,依此类推。在某些时候,某人需要知道具体类型是什么,并且有人传入public <T> boolean compare(Wrapper wrapper, Class<T> cls) { return cls.isInstance(wrapper.obj); } // and then, at the call site: if (compare(wrapper, Foo.class)) { ... }

答案 1 :(得分:1)

您不能引用类型参数的静态成员(例如您尝试以T.class的形式执行)。您也无法在instanceof表达式中有意义地使用它们。更一般地说,因为Java泛型是通过类型擦除实现的,所以在运行时不能以任何方式使用类型参数 - 所有类型分析都是在编译时静态执行的。

根据您的具体情况,至少有两种替代方法。

第一种,更常见的是确保可以静态检查必要的类型。例如,您可以使用它包装的对象的类型来参数化Wrapper类。然后,假设您在类型安全的程序中使用它,只要您有Wrapper<String>,就知道包装的对象是String

如果要验证包装对象的特定类,但是,当要测试的类不是final时,这不能很好地工作。在这种情况下,你可以传递一个Class对象,如下所示:

<T> boolean compare(Wrapper<? super T> wrapper, Class<T> clazz) {
    return wrapper.obj.getClass().equals(clazz);
}

它根据指定的类检查包装对象的类,只允许在静态分析允许它返回true的情况下调用该方法。

如果愿意,您可以实际组合这两种方法来创建一个Wrapper类,其实例只能包含特定类的成员,而不是任何可分配给给定类型的对象。不过,我不确定你为什么要那样做。