instanceof vs getClass( )

2022-08-31 08:13:54

我看到使用和操作员在操作员上的性能有所提高。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


答案 1

和 的性能之所以不同,是因为它们在做不同的事情。instanceofgetClass() == ...

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

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

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

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

不一定。过度使用其中任何一种,也可能是“设计气味”。如果你不小心,你最终会得到一个设计,其中添加新的子类会导致大量的代码返工。在大多数情况下,首选方法是使用多态性。instanceOfgetClass()

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


“最佳实践”、“不良实践”、“设计气味”、“反模式”等术语应谨慎使用,并应谨慎对待。他们鼓励非黑即白的思维。最好在上下文中做出判断,而不是纯粹基于教条;例如,某人说是“最佳实践”我建议每个人阅读No Best Practices,如果他们还没有这样做的话。


答案 2

是否要完全匹配类,例如,仅匹配而不是 ?如果是这样,请使用 和 。我通常会在 中执行此操作,以便 X 的实例不被视为等于 X 的子类的实例 - 否则您可能会遇到棘手的对称问题。另一方面,这通常用于比较两个对象属于一类而不是一个特定类。FileInputStreamFileInputStreamgetClass()==equals

否则,请使用 。请注意,您需要确保开始时有一个非空引用,否则您将获得一个 ,而如果第一个操作数为 null,则只会返回。instanceofgetClass()NullPointerExceptioninstanceoffalse

就个人而言,我会说这是更惯用的 - 但在大多数情况下,广泛使用它们中的任何一个都是一种设计气味。instanceof