2009-09-11 58 views
1

说我有3类,像这样:有没有办法确定一个类是Java中的一个实例?

class A {} 
class B extends A {} 
class C extends A {} 

难道然后才有可能确定特定对象是否是的AB,或C一个实例?

我认为,这样的事情可能工作:

if (myObject.getClass().isInstance(B.class)) { 
    // do something for B 
} else (myObject.getClass().isInstance(C.class)) { 
    // do something for C 
} else { 
    // do something for A 
} 

但阅读一点点,我认为这将始终评估为B,因为它只是测试,如果铸造会工作,还有他们之间没有本质区别了。

回答

7

这样做:

if (myObject instanceof B) { 
    // do something for B 
} else (myObject instanceof C) { 
    // do something for C 
} else { 
    // do something for A 
} 
+0

谢谢...正是我一直在寻找。 – 2009-09-11 07:19:40

9

的更简单,更快速的代码是:

if (myObject instanceof B) { 
} else if (myObject instanceof C) { 
} else if (myObject instanceof A) { 
} 

注意顺序很重要:你必须有测试为A最后,因为这会为成功还有BC的实例。

但是,您的原始代码几乎可以工作。 Class.isInstance检查值是否真的是给定类或任何超类的实例。因此,如果myObjectC的实例,则B.class.isInstance(myObject)将返回false。所有你有错的是你正在呼吁myObjectgetClass()不必要的,而不是使用B.class

这是,如果你不知道你是哪个班在编译时兴趣,你会采取的方法 - instanceof运算符仅在您可以在代码中静态指定类型时才起作用。

现在,如果你想找出是否myObject实例正是B(而不是一个子类),则只需使用:

if (myObject.getClass() == B.class) 

(这将炸毁,如果myObject是空引用,当然)。

+0

在典型的堆叠覆盖面上回答...我的意思是,Skeet矫枉过正的样式。 :d – Epaga 2009-09-11 09:21:54

0

有一个instanceof运营商,可以做你想做的,就像其他人已经回答的一样。

但请注意,如果您需要这样的事情,这表明您的程序设计中可能存在缺陷。更好,更面向对象的方法是通过使用多态性:在超类A中放置一个方法,在B和C中重写该方法,并在myObject上调用该方法(应该具有类型A):

A myObject = ...; // wherever you get this from 

// Override someMethod in class B and C to do the things that are 
// specific to those classes 
myObject.someMethod(); 

instanceof是丑陋的,应尽可能避免,就像铸造丑陋,可能不安全,应该避免。

1

你也可能想看看double dispatch idiom,这是一种OO方式,根据不支持多方法的语言的参数类型来改变行为。

0

,你可以快速回复做到这一点

if (myObject.getClass() == B.class) { 
    // do something for B (not subclasses of b!!!) 
} else if(myObject.getClass() == C.class) { 
    // do something for C (not subclasses of c!!!) 
} else if(myobject.getClass() == A.class) { 
    // do something for A (not subclasses of A!!) 
} else if(myobjects instanceof A){ 
    //all other subclasses of A 
} 
相关问题