instanceof Vs getClass()

blo*_*lob 106 java class instanceof

当使用getClass()==运算符over 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));
Run Code Online (Sandbox Code Playgroud)

是否有任何准则,哪一个使用getClass()instanceOf

给定一个情景:我知道要匹配精确类,即String,Integer(这些都是final类)等.

使用instanceOf运算符不好的做法?

Ste*_*n C 131

表现instanceofgetClass() == ...不同的原因是他们做了不同的事情.

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

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

所以建议忽略性能问题,并使用替代方案为您提供所需的答案.

是的,过度使用其中任何一个都可能是"设计气味".如果您不小心,最终会得到一个设计,其中添加新的子类会导致大量的代码重新编写.在大多数情况下,首选方法是使用多态.

有些情况下这些不是"设计气味".例如,equals(Object)您需要测试参数的实际类型,false如果不匹配则返回.这最好用getClass().

  • @overexchange - 您无法有效地推断出所有使用`instanceof`(例如)都是糟糕的设计.在某些情况下,它可能是最好的解决方案.对于`getClass()`也是一样的.我会重申,我说**"过度使用"**而不是**"使用"**.每个案件都需要根据其优点来判断......而不是盲目地应用一些没有根据的教条法则. (4认同)

Jon*_*eet 39

你想要完全匹配一个类,例如只匹配FileInputStream而不是任何子类FileInputStream吗?如果是这样,请使用getClass()==.我通常会在一个中执行此操作equals,因此X的实例不被视为等于X的子类的实例 - 否则您可能会陷入棘手的对称问题.另一方面,这通常用于比较两个对象与一个特定类相同的类.

否则,请使用instanceof.请注意,getClass()您将需要确保您有一个非空引用,或者您将得到一个NullPointerException,而如果第一个操作数为null ,则只instanceof返回false.

就个人而言,我认为instanceof这更具惯用性 - 但在大多数情况下,广泛使用其中任何一种都是一种设计气味.


And*_*der 18

我知道这已经有一段时间了,但我昨天学到了另一种选择

我们都知道你可以这样做:

if(o instanceof String) {   // etc
Run Code Online (Sandbox Code Playgroud)

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

if(o instanceof <Class variable>.getClass()) {   
Run Code Online (Sandbox Code Playgroud)

因为它给出了编译错误.
相反,这是一个替代方案 - isAssignableFrom()

例如:

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

    return classTypeWeWant.isAssignableFrom(objectWeHave.getClass())
}
Run Code Online (Sandbox Code Playgroud)

  • 不要使用`isAssignableFrom`.使用反射编写`o instanceof String`的正确方法是[`String.getClass().isInstance(o)`](https://docs.oracle.com/javase/10/docs/api/java/lang/ Class.html#isInstance(java.lang.Object中)).javadoc甚至这样说:*这个方法是Java语言`instanceof`操作符的动态等价物.* (4认同)