为什么 m 方法的可见性会以这种方式改变输出?我预计会发生相反的情况
Why does the visibility of m method change the output in this way? I expected the opposite to occur
标题编辑:"my* method"所以问题的根源是方法pmA3。它同时出现在 class A 和 class B 中。方法查找会建议当 pmA3 被调用时,它会在 class B 中查找方法并在查找之前执行该方法class 中的方法 A. 更改为 public 给出了预期的结果,但我不知道为什么。不应该反过来吗?
public class Class {
public static void main(String[] args) {
B bVar = new B();
bVar.mA1();
bVar.mA2();
}
}
class A {
public A() {
System.out.println("A");
}
private void pmA3() {
System.out.println("pmA3 - A");
}
public void mA1() {
System.out.println("mA1 - A");
}
public void mA2() {
System.out.println("mA2 - A");
pmA3();
}
}
class B extends A {
public void pmA3() {
System.out.println("pmA3 - B");
}
public void mA1() {
System.out.println("mA1 - B");
}
public void mB1() {
System.out.println("mB1 - B");
}
}
Expected Results:
A
mA1 - B
mA2 - A
pmA3 - B
Actual Results:
A
mA1 - B
mA2 - A
pmA3 - A
JLS §8.4.8说明私有方法不被继承
实际上,class A
中对 pmA3()
的调用是 静态 绑定的。 IE。它在 编译时 得到解决。由于调用在 class A
内,它将调用方法 A#pmA3
.
当您将方法声明为 public 时,上面提到的 JLS 段落告诉您,它现在是可继承的。
因此,在您的 class A
中对 pmA3()
的调用现在 动态 绑定。 IE。编译器不解析要调用的具体方法,而是将其委托给运行时间。在 运行 时间,JVM 查找调用该方法的对象的具体类型以及该类型是否具有重写的方法。在您的情况下是这样,因此将调用方法 B#pmA3
。
标题编辑:"my* method"所以问题的根源是方法pmA3。它同时出现在 class A 和 class B 中。方法查找会建议当 pmA3 被调用时,它会在 class B 中查找方法并在查找之前执行该方法class 中的方法 A. 更改为 public 给出了预期的结果,但我不知道为什么。不应该反过来吗?
public class Class {
public static void main(String[] args) {
B bVar = new B();
bVar.mA1();
bVar.mA2();
}
}
class A {
public A() {
System.out.println("A");
}
private void pmA3() {
System.out.println("pmA3 - A");
}
public void mA1() {
System.out.println("mA1 - A");
}
public void mA2() {
System.out.println("mA2 - A");
pmA3();
}
}
class B extends A {
public void pmA3() {
System.out.println("pmA3 - B");
}
public void mA1() {
System.out.println("mA1 - B");
}
public void mB1() {
System.out.println("mB1 - B");
}
}
Expected Results:
A
mA1 - B
mA2 - A
pmA3 - B
Actual Results:
A
mA1 - B
mA2 - A
pmA3 - A
JLS §8.4.8说明私有方法不被继承
实际上,class A
中对 pmA3()
的调用是 静态 绑定的。 IE。它在 编译时 得到解决。由于调用在 class A
内,它将调用方法 A#pmA3
.
当您将方法声明为 public 时,上面提到的 JLS 段落告诉您,它现在是可继承的。
因此,在您的 class A
中对 pmA3()
的调用现在 动态 绑定。 IE。编译器不解析要调用的具体方法,而是将其委托给运行时间。在 运行 时间,JVM 查找调用该方法的对象的具体类型以及该类型是否具有重写的方法。在您的情况下是这样,因此将调用方法 B#pmA3
。