if(x instanceof X)的奇怪行为

时间:2013-05-01 17:23:21

标签: java class inheritance instanceof

我有一个班级PartA和一个班级PartB,它是PartA的派生类。 我有一个PartA类型的列表,其中包含a和b部分。 我需要确定当我循环它时它实际上是哪种类。 但如果我这样做:

for (PartA i : parts) {
    if (i instanceof PartA) {
        //some logic
    }

无论实际是哪个类,它仍然会成立:a或b。

我做错了什么,或者如果没有,我能做些什么来达到预期的效果呢?

4 个答案:

答案 0 :(得分:6)

PartB 的实例也是PartA实例。始终首先检查派生类型最多。 (阅读instanceof X为“是X的实例或X的派生类型。”)

或者,更好的是,将多态性用于您的优势 - 可以将此逻辑转移到PartA的方法中,您可以覆盖PartB吗?那么你就不必实际测试对象的类型,你只需要让虚拟方法调度为你找出它。

答案 1 :(得分:3)

此行为是设计使然 B的实例也是A的实例。

你想要

if (i.getClass() == A.class)

答案 2 :(得分:2)

此处instanceof的行为与JLS15.20.2中指定的相同。根据其中:

  

在运行时,如果是,则instanceof运算符的结果为true   RelationalExpression的值不为null,引用可以   被投射(§15.16)到ReferenceType 而不提出一个   ClassCastException异常。否则结果是错误的。

在您的情况下,i是引用,它是引用类型PartA的子类型。因此,它始终返回true。你应该使用:

 if((i.getClass().getName()).equals(A.class.getName()))

答案 3 :(得分:1)

鉴于您从PartB继承PartAPartB PartA,因此a instanceof PartA始终为true {1}}。为了区分它们,您需要测试它是否为PartB