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

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

做这个:

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

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

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

请注意,顺序很重要:您必须对A最后一次测试,因为对于BC实例也是如此。

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

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

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

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

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

您还可能希望查看双调度习惯用法 ,这是一种基于不支持多方法的语言中的参数类型来改变行为的OO方式。

正如其他人已经回答的那样,有一个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是丑陋的,应尽可能避免,就像铸造丑陋,可能不安全,应该避免。

你可以做到这一点

 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 }