我有一个类PartA和一个类PartB,它是PartA. 我有一个PartA包含 a 和 b 部分的类型列表。当我遍历它时,我需要确定它实际上是哪种类。但如果我这样做:
for (PartA i : parts) {
if (i instanceof PartA) {
//some logic
}
无论它实际上是哪个类,它仍然会给出 true:a 或 b。
我做错了什么,或者如果没有,我该怎么做才能达到预期的结果?
我有一个类PartA和一个类PartB,它是PartA. 我有一个PartA包含 a 和 b 部分的类型列表。当我遍历它时,我需要确定它实际上是哪种类。但如果我这样做:
for (PartA i : parts) {
if (i instanceof PartA) {
//some logic
}
无论它实际上是哪个类,它仍然会给出 true:a 或 b。
我做错了什么,或者如果没有,我该怎么做才能达到预期的结果?
的实例PartB 也是 的实例PartA。始终首先检查最派生的类型。(读instanceof X作“是 的实例X或派生类型X。”)
或者,更好的是,使用多态对你有利——这个逻辑可以转移到PartA你可以覆盖的方法中PartB吗?然后你就不必实际测试对象的类型,你只需让虚拟方法调度为你解决这个问题。
此行为是设计使然。
的实例B也是 的实例A。
你要
if (i.getClass() == A.class)
这instanceof是JLS15.20.2中指定的行为。根据该:
在运行时,如果 RelationalExpression 的值不为 null 并且可以将引用强制转换(第 15.16 节)到 ReferenceType而不会引发 ClassCastException,则 instanceof 运算符的结果为真。否则结果为假。
在您的情况下i是引用,它是引用类型的子类型PartA。因此它总是返回true。你应该使用:
if((i.getClass().getName()).equals(A.class.getName()))
鉴于您对PartBfrom的继承PartA,aPartB 是a PartA,所以a instanceof PartA永远都是true。要区分它们,您需要测试它是否为PartB.