instanceof 与 getClass( )

问题描述 投票:0回答:4

我发现使用

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

给定一个场景:我知道要匹配的确切类,即

String
Integer
(这些是最终类)等

使用

instanceOf
运算符是不好的做法吗?

java class instanceof
4个回答
174
投票

instanceof
getClass() == ...
的性能不同的原因是他们在做不同的事情。

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

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

因此建议忽略性能问题并使用能为您提供所需答案的替代方案。

使用

instanceOf
运算符是不好的做法吗?

不一定。 过度使用

instanceOf
getClass()
可能是“设计味道”。 如果您不小心,您最终会得到这样的设计:添加新子类会导致大量代码返工。 在大多数情况下,首选方法是使用多态性。

然而,在某些情况下这些并不是“设计气味”。 例如,在

equals(Object)
中,您需要测试参数的实际类型,如果不匹配则返回
false
。 最好使用
getClass()
来完成此操作。


应谨慎使用“最佳实践”、“不良实践”、“设计味道”、“反模式”等术语,并以怀疑的态度对待。 他们鼓励非黑即白的思维。 最好根据具体情况做出判断,而不是纯粹基于教条;例如有人说这是“最佳实践”。 我建议每个人都阅读没有最佳实践(如果他们还没有这样做的话)。


49
投票

您想要完全匹配某个类别吗?只匹配 FileInputStream

 而不是 
FileInputStream
 的任何子类?如果是这样,请使用 
getClass()
==
。我通常会在 
equals
 中执行此操作,以便 X 的实例不被视为等于 X 子类的实例 - 否则您可能会遇到棘手的对称问题。另一方面,这通常对于比较两个对象属于“相同”类比比较一个特定类更有用。
否则,请使用 instanceof

。请注意,使用

getClass()

 时,您需要确保开始时有一个非空引用,否则您将得到 
NullPointerException
,而 
instanceof
 如果第一个操作数为空,则仅返回 
false
我个人认为 
instanceof

更惯用 - 但在大多数情况下,广泛使用

 中的任何一个都是一种设计味道。
    


18
投票
我知道自从问这个问题以来已经有一段时间了,但我昨天学到了另一种选择

我们都知道你可以做到:

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()) }
    

3
投票
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的实例。

subClassInstance 和parentClassInstance 的getClass() 返回结果不同。

© www.soinside.com 2019 - 2024. All rights reserved.