我有一个班级PartA
和一个班级PartB
,它是PartA
的派生类。
我有一个PartA
类型的列表,其中包含a和b部分。
我需要确定当我循环它时它实际上是哪种类。
但如果我这样做:
for (PartA i : parts) {
if (i instanceof PartA) {
//some logic
}
无论实际是哪个类,它仍然会成立:a或b。
我做错了什么,或者如果没有,我能做些什么来达到预期的效果呢?
答案 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
继承PartA
,PartB
为PartA
,因此a instanceof PartA
始终为true
{1}}。为了区分它们,您需要测试它是否为PartB
。