有没有办法确定类是Java的实例的类型?
假设我有3个类,如下所示:
class A {} class B extends A {} class C extends A {}
那么可以确定特定对象是A
, B
还是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
最后一次测试,因为对于B
和C
实例也是如此。
但是,您的原始代码几乎可以正常工作。 Class.isInstance
检查值是否确实是给定类或任何超类的实例。 因此,如果myObject
是C
的实例,那么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 }