有没有办法确定类是Java中的实例的类型?

时间:2009-09-11 07:13:52

标签: java oop class inheritance

说我有3个这样的课程:

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,因为它只是测试一个演员是否有效并且它们之间没有实质性差异。

5 个答案:

答案 0 :(得分: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。你所犯的错误就是你在getClass()上不必要地拨打myObject,而不是使用B.class等。

如果您在编译时不知道自己感兴趣的类,那么这就是您要采用的方法 - instanceof运算符仅在您可以在代码中静态指定类型时才有效。

现在,如果你想知道myObject的实例 B(而不是子类),那么只需使用:

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

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

答案 1 :(得分:7)

这样做:

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

答案 2 :(得分:1)

您还可能希望查看double dispatch idiom,它是根据不支持多方法的语言中的参数类型更改行为的OO方式。

答案 3 :(得分: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是丑陋的,应该尽可能地避免,就像铸造丑陋,可能不安全一样,应该避免。

答案 4 :(得分: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
}