假设我们有一个方法接受两个类型为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; }
后一种选择相当缓慢。这个问题还有其他替代方案吗?
答案 0 :(得分:10)
不要打扰完全限定的类名 - 只需比较类引用:
public boolean foo(Object o1, Object o2) {
return o1.getClass() == o2.getClass();
}
类通过名称和类加载器本质上是唯一的 - 所以如果对象属于同一个类 name 但是由不同的类加载器加载,这将返回false,但这可能是合适的:它们可能是完全不同的类除了名字之外!但是,如果类具有相同的名称和类加载器,则它们将具有相同的引用。
请注意,如果NullPointerException
或o1
为空,则会抛出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();
}
确保在对象中提供身份。