instanceof Vs getClass()

时间:2011-02-14 07:40:23

标签: java class instanceof

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运算符不良做法?

4 个答案:

答案 0 :(得分:128)

instanceofgetClass() == ...的效果不同的原因是它们正在做不同的事情。

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

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

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

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

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

答案 1 :(得分:37)

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

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

我个人认为instanceof更具惯用性 - 但在大多数情况下,广泛使用 是一种设计气味。

答案 2 :(得分:17)

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

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

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 :(得分:2)

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 ");
        }
    }
}

输出:

SubClass扩展了ParentClass。 subClassInstance是parentC的instanceof。

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