Java 为什么这两种情况下的输出不同?
为什么在以下情况下,即使变量已被重写,输出也会不同Java 为什么这两种情况下的输出不同?,java,field,shadowing,member-hiding,Java,Field,Shadowing,Member Hiding,为什么在以下情况下,即使变量已被重写,输出也会不同 public class A { int a = 500; void get() { System.out.println("a is " + this.a); } } public class B extends A { int a = 144; } public class mainmethod { public static void main(String args[]) {
public class A {
int a = 500;
void get() {
System.out.println("a is " + this.a);
}
}
public class B extends A {
int a = 144;
}
public class mainmethod {
public static void main(String args[]) {
B ob = new B();
System.out.println("a is " + ob.a);
ob.get();
}
}
在执行
ob.a
时,从ob
对象中获取变量inta
,该对象是类B
的对象
但是,当您执行
ob.get()时
,您正在从类A
调用get()
-方法,因为B
中没有get()
,正如您所写的那样,它使用this.A
,在这种情况下,它将是类A
的int A
。没有被重写的变量B
实际上有两个名为a
的实例变量:一个声明,另一个继承。见此:
B ob = new B();
System.out.println("B.a is " + ob.a);
System.out.println("A.a is " + ((A)ob).a);
在
B
的实例方法中,您可以编写super.a
或((a)this).a
来访问父变量。否该变量不会被覆盖。
ob.a
打印B类的a变量。
ob.get()
在B类中搜索get方法。当它没有到达那里时,它会搜索父类并执行它。它被称为“字段隐藏”或“阴影”。查看更多问题(和答案):感谢您的回复!您需要记住一条简单的规则:“字段不是多态的”。多态性(后期/动态绑定)仅适用于非静态/最终/私有的方法。有趣的是(对初学者来说,这是相当令人困惑的)部分是在get()中打印它B@XXXSlightly令人困惑但也是正确的:
B
同时包含这两个变量,这都是关于名称解析规则的,您可以无条件访问其中一个。但底线是:不要这样做。但是在字节码的局部变量表中,您可以看到this
的签名是LA
肯定的,因为它是在A
中声明的。this
的静态类型肯定是A
this。A
基于this
而变化,但是,this
将在A
中打印相同的内容^--^