将Java Type与Class进行比较

时间:2014-02-26 12:07:21

标签: java reflection

我把这个简单的例子放在一起有点麻烦。

通过反射,我可以获得某种声明字段的类型。但是,我如何将其与已知类进行比较?

我想做的是:

Type t = myField.getType();
if (t.equals(MyOwnClass.class)) {
    // Now I know myField is of type MyOwnClass
}

2 个答案:

答案 0 :(得分:0)

您可以使用

功能
isAssignableFrom() 

确定这一点。注意,也允许继承类。

Type t = myField.getType();
if (t.isAssignableFrom(MyOwnClass.class)) {
    // Now I know myField is of type MyOwnClass
}

答案 1 :(得分:0)

基本上,您已经找到了正确的答案,只需要进行一些评论。另一个答案是错误的。

首先,getType()返回Class<?>引用,具有实现Type接口的Class类;使用Type变量进行isAssignableFrom()调用是错误的,原因有两个:

  • 类型没有isAssignableFrom方法()
  • Class#isAssignableFrom()需要Class<?>参数,而不是类型参数

简单地说,你可能不应该以这种方式比较一个类/类型,因为你隐藏了相关的输入并需要不必要的转换。另一方面,你刚刚升级了Class<?>引用类型引用,并且因为在类上调用的equals()(甚至是类型转换为实际)实际上调用了Object#equals,它只是调用

public boolean equals(Object obj) {
    return (this == obj);
}

直接来自Object.java,因为Class.java不以任何方式覆盖它。

其次,你可以做你已经完成的事情,但这是正确的方法之一:

if ( myField.getType() == MyOwnClass.class ) {
    // Now I know myField is of type MyOwnClass
} // note that this requires a single ClassLoader to be used! Two ClassLoaders could in theory load one class with two separate Class instances

或者,你可以

if ( myField.getType().getCanonicalName().equals( MyOwnClass.class.getCanonicalName() ) {
    // Now I know myField is of type MyOwnClass
} // note that this uses a name comparison, not a class comparison

甚至

if ( myField.getType().isAssignableFrom( MyOwnClass.class )) {
  // Now I know MyOwnClass objects can be cast to myField.getType() safely
} // note: they are either equal or MyOwnClass is a subclass of myField.getType()

tl; dr这里不需要在Class对象上使用equals(),因为两个相等的类必须是==无论如何,就像转换为Type一样 - 仍然,你在问题中提供的答案确实是一个有效的解决方案。