我发现使用
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
运算符是不好的做法吗?
instanceof
和getClass() == ...
的性能不同的原因是他们在做不同的事情。
instanceof
测试左侧 (LHS) 的对象引用是否是右侧 (RHS) 类型的实例或某个子类型。
getClass() == ...
测试类型是否相同。
因此建议忽略性能问题并使用能为您提供所需答案的替代方案。
使用
运算符是不好的做法吗?instanceOf
不一定。 过度使用
instanceOf
或 getClass()
可能是“设计味道”。 如果您不小心,您最终会得到这样的设计:添加新子类会导致大量代码返工。 在大多数情况下,首选方法是使用多态性。
然而,在某些情况下这些并不是“设计气味”。 例如,在
equals(Object)
中,您需要测试参数的实际类型,如果不匹配则返回 false
。 最好使用 getClass()
来完成此操作。
应谨慎使用“最佳实践”、“不良实践”、“设计味道”、“反模式”等术语,并以怀疑的态度对待。 他们鼓励非黑即白的思维。 最好根据具体情况做出判断,而不是纯粹基于教条;例如有人说这是“最佳实践”。 我建议每个人都阅读没有最佳实践(如果他们还没有这样做的话)。
您想要完全匹配某个类别吗?只匹配 FileInputStream
而不是
FileInputStream
的任何子类?如果是这样,请使用
getClass()
和
==
。我通常会在
equals
中执行此操作,以便 X 的实例不被视为等于 X 子类的实例 - 否则您可能会遇到棘手的对称问题。另一方面,这通常对于比较两个对象属于“相同”类比比较一个特定类更有用。否则,请使用
instanceof
。请注意,使用 getClass()
时,您需要确保开始时有一个非空引用,否则您将得到
NullPointerException
,而
instanceof
如果第一个操作数为空,则仅返回
false
。
我个人认为
instanceof
更惯用 - 但在大多数情况下,广泛使用 中的任何一个都是一种设计味道。
我们都知道你可以做到:
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())
}
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() 返回结果不同。