为啥 m 方法的可见性会以这种方式改变输出?我预计会发生相反的情况[重复]

Posted

技术标签:

【中文标题】为啥 m 方法的可见性会以这种方式改变输出?我预计会发生相反的情况[重复]【英文标题】:Why does the visibility of m method change the output in this way? I expected the opposite to occur [duplicate]为什么 m 方法的可见性会以这种方式改变输出?我预计会发生相反的情况[重复] 【发布时间】:2019-09-01 20:00:34 【问题描述】:

标题编辑:“my* 方法” 所以问题的根源是方法 pmA3。它存在于 A 类和 B 类中。方法查找会建议当 pmA3 被调用时,它会在 B 类中查找方法并在它在 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

【问题讨论】:

你说的“改成公众号”是什么意思?你没有展示它不公开的情况......你怎么能得到这个结果,因为你从来没有打电话给pmA3() 【参考方案1】:

JLS §8.4.8 说明私有方法不会被继承。

事实上,在你的类A 中对pmA3() 的调用是静态 绑定的。 IE。它在编译时解决。由于调用在类A 内,它将调用方法A#pmA3

当您将方法声明为公共时,上面提到的 JLS 段落会告诉您,它现在是可继承的。

因此,在您的类A 中对pmA3() 的调用现在是动态 绑定的。 IE。编译器不会解析要调用的具体方法,而是将其委托给运行时。在运行时,JVM 查找调用该方法的对象的具体类型以及该类型是否具有被覆盖的方法。在您的情况下是这样,因此将调用方法 B#pmA3

【讨论】:

以上是关于为啥 m 方法的可见性会以这种方式改变输出?我预计会发生相反的情况[重复]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Node.js 会以这种方式执行?

Elixir:应用程序立即退出,或者在运行 distillery 包时没有收到输入。为啥它会以这种方式工作,以及如何解决它?

为啥在将 First() 应用于投影时,此 linq 代码会以指数方式变慢?

为啥 IE 会以不同的方式呈现这个 HTML 表格?

为啥 Visual Studio 在调试时会以不同的方式处理 ANSI Escape 代码?

为啥这个非常棘手的计算属性名称函数会以它的方式工作?