Instanceof Vs getClass()

当使用 getClass()==操作符而不是 instanceOf操作符时,我看到了性能的提高。

Object  str = new Integer("2000");


long starttime = System.nanoTime();


if(str instanceof String) {
System.out.println("its string");
} else {
if (str instanceof Integer) {
System.out.println("its integer");


}
}


System.out.println((System.nanoTime()-starttime));


starttime = System.nanoTime();


if(str.getClass() == String.class) {
System.out.println("its string in equals");
} else {
if(str.getClass() == Integer.class) {
System.out.println("its integer");
}
}


System.out.println((System.nanoTime()-starttime));

有没有使用 getClass()instanceOf的指导方针?

给出一个场景: 我知道要匹配的确切类,即 StringInteger(这些是最终类)等。

使用 instanceOf操作符是不好的做法吗?

144791 次浏览

您是否希望匹配 没错类,例如只匹配 FileInputStream而不匹配 FileInputStream的任何子类?如果是,使用 getClass()==。我通常会在 equals中这样做,这样 X 的实例就不会被认为等于 X 的子类的实例-否则你可能会遇到棘手的对称性问题。另一方面,对于比较两个 一样类的对象比一个特定类的对象更有用。

否则,使用 instanceof。注意,对于 getClass(),您需要确保开始时有一个非空引用,否则您将获得一个 NullPointerException,而如果第一个操作数为空,则 instanceof将仅返回 false

我个人认为 instanceof更加地道——但是广泛使用 都不是在大多数情况下是一种设计气味。

instanceofgetClass() == ...之所以表现不同,是因为它们做的事情不同。

  • instanceof测试左侧的对象引用(LHS)是否是右侧类型(RHS) 或者某种亚型的实例。

  • getClass() == ... 测试这些类型是否相同。

因此,建议忽略性能问题,使用能够给出所需答案的替代方案。

使用 instanceOf操作员是不好的做法吗?

不一定。过度使用 instanceOfgetClass() 也许吧“设计气味”。如果不小心,最终的设计将导致添加新的子类导致大量代码返工。在大多数情况下,首选的方法是使用多态性。

然而,有些情况下,这些不是“设计气味”。例如,在 equals(Object)中,需要测试参数的实际类型,如果不匹配,则返回 false。这最好使用 getClass()完成。


“最佳实践”、“糟糕实践”、“设计味道”、“反模式”等术语应该谨慎使用,并且要持怀疑态度。他们鼓励非黑即白的思维。最好是在上下文中做出判断,而不是纯粹基于教条; 例如某人说的“最佳实践”。我建议大家阅读 没有最佳实践,如果他们还没有这样做。

我知道已经有一段时间没有人问过我这个问题了,但是我昨天学到了一个替代方案

我们都知道你可以做:

if(o instanceof String) {   // etc

但是如果您不知道它需要是什么类型的类呢? 你不能一般地这样做:

if(o instanceof <Class variable>.getClass()) {

因为它会出现编译错误。
相反,这里有一个替代方案-isAssignableFrom ()

例如:

public static boolean isASubClass(Class classTypeWeWant, Object objectWeHave) {


return classTypeWeWant.isAssignableFrom(objectWeHave.getClass())
}

GetClass ()有一个限制,即对象只等于同一类的其他对象,同一运行时类型,如下面代码的输出所示:

class ParentClass{
}
public class SubClass extends ParentClass{
public static void main(String []args){
ParentClass parentClassInstance = new ParentClass();
SubClass subClassInstance = new SubClass();
if(subClassInstance instanceof ParentClass){
System.out.println("SubClass extends ParentClass. subClassInstance is instanceof ParentClass");
}
if(subClassInstance.getClass() != parentClassInstance.getClass()){
System.out.println("Different getClass() return results with subClassInstance and parentClassInstance ");
}
}
}

产出:

SubClassInstance 是 ParentClass 的 instanceof。

使用 subClassInstance 和 ParentClassInstance 返回不同的 getClass ()结果。