为什么不根据其对象的运行时类型来选择此方法?
考虑一下:
class A {
int x =5;
}
class B extends A{
int x =6;
}
public class CovariantTest {
public A getObject() {
return new A();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
CovariantTest c1 = new SubCovariantTest();
System.out.println(c1.getObject().x);
}
}
class SubCovariantTest extends CovariantTest {
public B getObject(){
return new B();
}
}
据我所知,JVM 根据其对象的真实类型来选择方法。这里真正的类型是 SubCovariantTest,它定义了一个重写方法 getObject。
程序打印 5,而不是 6。为什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
该方法确实是由对象的运行时类型选择的。运行时类型没有选择的是整数字段
x
。B
对象存在两个x
副本,一份用于Ax
,一份用于Bx
。您静态从A
类中选择字段,作为getObject
返回的对象的编译时类型是A
。可以通过向A
和B
添加方法来验证这一事实:并将测试表达式更改为:
The method is indeed chosen by the runtime type of the object. What is not chosen by the runtime type is the integer field
x
. Two copies ofx
exist for theB
object, one forA.x
and one forB.x
. You are statically choosing the field fromA
class, as the compile-time type of the object returned bygetObject
isA
. This fact can be verified by adding a method toA
andB
:and changing the test expression to:
除非我弄错了,否则默认情况下方法在 java 中是虚拟的,因此您可以正确地覆盖该方法。然而字段(如“x”)不是虚拟的并且不能被覆盖。当您在 B 中声明“int x”时,您实际上是在创建一个全新的变量。
多态性不会对字段生效,因此当您尝试在转换为类型 A 的对象上检索 x 时,您将得到 5,如果该对象转换为类型 B,您将得到 6。
Unless I'm mistaken, methods are virtual in java by default, so you're overriding the method properly. Fields however (like 'x') are not virtual and can't be overriden. When you declare "int x" in B, you are actually creating a totally new variable.
Polymorphism doesn't go into effect for fields, so when you try and retrieve x on an object casted to type A, you will get 5, if the object is casted to type B, you will get 6.
当超类和子类中的字段具有相同名称时,称为“隐藏”。除了问答中提到的问题之外,还有其他方面可能会引起微妙的问题:
来自 http://java.sun.com/docs/books/tutorial/java/IandI/hidevariables.html
有些编译器会警告隐藏变量
When fields in super and subclasses have the same names it is referred to as "hiding". Besides the problems mentioned in the question and answer there are other aspects which may give rise to subtle problems:
From http://java.sun.com/docs/books/tutorial/java/IandI/hidevariables.html
Some compilers will warn against hiding variables