在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
运算符不良做法?
答案 0 :(得分:128)
instanceof
和getClass() == ...
的效果不同的原因是它们正在做不同的事情。
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的结果。