java 中是如何确认要调用哪一个方法的?

下面是代码:

public class Entrance {
    public static void main(String[] args) {
        A b = new B();
        b.test();
    }
}

class A {
   public void test() {
       this.debug();
   }

   private void debug() {
       System.out.println("A debug");
   }
}

class B extends A {
    public void debug() {
        System.out.println("B debug");
    }
}

运行结果为:A debug

public class Entrance {
    public static void main(String[] args) {
        A b = new B();
        b.test();
    }
}

class A {
   public void test() {
       this.debug();
   }

   //这里把private 变为了public
   public void debug() {
       System.out.println("A debug");
   }
}

class B extends A {
    public void debug() {
        System.out.println("B debug");
    }
}

运行结果为:B debug

个人是这样认为的:
运行时类型决定了方法的调用,当前的运行时类型为B;
从B类开始寻找test() 方法,找不到,就向父类A继续寻找,在A类中找到了;
开始执行test() 方法, 方法体中执行this.debug() 方法,this对象此时是B类对象,所以在B类中寻找,B中存在debug() 方法,并且可以访问;
所以个人认为应该直接输出B debug 才对, 但是第一种情况输出了A debug,不清楚是因为什么,希望有大佬可以解释下,非常感谢

阅读 3.5k
4 个回答

https://javarevisited.blogspo...

https://dev.to/sumit/static-v...

感谢各位大佬,上面的文章解决了我的疑惑,个人认为是由静态绑定决定的;
private, final and static methods and variables use static binding and are bonded by the compiler while virtual methods are bonded during runtime based upon runtime object.

private方法不能被重写啊。

debug 方法是 private 的时候,bdebug 方法 和 adebug 方法之间没有重写的关系,所以 test 方法始终会调用 adebug
而当 debug 方法是 public 的时候,bdebug 方法 重写了 adebug 方法,因此 B 类型对象的 test 会调用到 bdebug 方法而不再是 a

因为写法一里没有覆盖/重写(Override),Java 并不认为 A.debugB.debug 是同一个方法、二者也没有覆写关系,所以父类接着调用父类的方法。换句话说,子类里根本不知道父类里有个 debug 方法。

写法二里是覆盖。

Can we override private methods in Java?
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题