我很困惑一个对象是instanceof
两个不同的类。例如:
EnglishTest x = new EnglishQuiz();
if (x instanceof EnglishTest){
System.out.print("P");
}
if (x instanceof EnglishQuiz){
System.out.print("P");
}
在这两种情况下,我都打印出“P”。我的问题是为什么?
我理解x
的类型为EnglishTest
,但由于我正在做new EnglishQuiz
,因此我不应该创建EnglishQuiz
而不是{{1}的实例还有?这里发生了什么?
答案 0 :(得分:5)
如果此行编译:
EnglishTest x = new EnglishQuiz();
然后is-a
和EnglishTest
之间必须存在EnglishQuiz
关系;具体而言,EnglishQuiz
必须是EnglishTest
的子类型,就像Integer
是Number
的方式一样。
因此,x instanceof EnglishTest
为真,同样Integer instanceof Number
为真。毕竟EnglishQuiz
是EnglishTest
。
查看Java语言规范Section 15.20.2:
在运行时,如果RelationalExpression的值不为null并且引用可以在不引发ClassCastException的情况下将引用(第15.16节)转换为ReferenceType,则instanceof运算符的结果为true。否则结果是错误的。
因为EnglishQuiz
总是可以转换为EnglishTest
(这样的转换被称为upcast并且总是被允许,因为对象总是被归类为其超类型),{{1 }}运算符返回instanceof
。
另一种可视化方式可能是:
true
如果 Object
|
Number
/ \
Integer Float
/ \
Pos. Neg.
/ \ / \
1 2 -4 -5
与x instanceof y
的类型相同,或者您可以从y
上升到x
, y
将返回true。
答案 1 :(得分:3)
class Test {
//implicitly inherits type Object
}
class Quiz extends Test {
//explicitly inherits type Test
//implicitly inherits type Object
}
class PopQuiz extends Quiz {
//explicitly inheirts type Quiz
//implicitly inheirts type Test and Object
}
Object -> Test -> Quiz -> PopQuiz
instanceof
指的是实例的类型。如果一个实例隐式或明确地"扩展"一个类,它是该类型的实例,因为它继承了它扩展的类的类型(以及任何其他扩展的类,如我的层次结构示例中所示)。
PopQuiz既是测验也是测试。因此,PopQuiz的一个实例继承了Quiz amd Test这两种类型,因此它是Quiz AND Test的一个实例。