如何判断两个参数是否是同一个但未知类的实例?

时间:2010-04-17 14:35:54

标签: java reflection types compare

假设我们有一个方法接受两个类型为Object的参数o1和o2,并返回一个布尔值。我希望这个方法只有在参数是同一个类的实例时才返回true,例如:

foo(new Integer(4),new Integer(5));

但是应该返回true:

foo(new SomeClass(), new SubtypeSomeClass());

应该返回false并且还:

foo(new Integer(3),"zoo");

应该返回false。

我认为一种方法是比较完全限定的类名:

public boolean foo(Object o1, Object o2){
 Class<? extends Object> c1 = o1.getClass();
 Class<? extends Object> c2 = o2.getClass();
 if(c1.getName().equals(c2.getName()){ return true;}
 return false;  
}

另一个条件陈述是:

if (c1.isAssignableFrom(c2) && c2.isAssignableFrom(c1)){ return true; }

后一种选择相当缓慢。这个问题还有其他替代方案吗?

2 个答案:

答案 0 :(得分:10)

不要打扰完全限定的类名 - 只需比较类引用:

public boolean foo(Object o1, Object o2) {
    return o1.getClass() == o2.getClass();
}

类通过名称和类加载器本质上是唯一的 - 所以如果对象属于同一个类 name 但是由不同的类加载器加载,这将返回false,但这可能是合适的:它们可能是完全不同的类除了名字之外!但是,如果类具有相同的名称和类加载器,则它们将具有相同的引用。

请注意,如果NullPointerExceptiono1为空,则会抛出o2,但这可能是您想要的。

答案 1 :(得分:0)

你的资格相当慢吗?相比什么?还请详细说明您的使用场景?在java中,Object api包含一个equals / hashCode方法,用于标识对象之间的相等性。看起来好像这是你可能试图找到的,即:

new Integer(4).equals(new Integer(5))

在这种情况下,在SomeClass中覆盖equals的最佳实现如下:

public boolean equals(Object obj) {
    if (obj instanceof SomeClass) {
        return ((SomeClass) obj).identityField.equals(identityField);
    }
    return false;
}
public int hashCode() {
    return 31 * identity.hashCode();
}

确保在对象中提供身份。