java 方法覆盖中的奇怪无限循环

Strange infinite loop in java method overriding

在尝试方法覆盖的不同排列组合时,我遇到了一个奇怪的无限循环。从超类中的增变器方法调用超类的重写方法时,程序进入无限循环。我使用的代码如下:

class A {
    private int x = 10;
     public void show() {
         System.out.println("Inside A's show showing private X: " + x);
     }
     
    public void change(int num) {
        this.x = num;
        // show(); Line 1
        this.show();  // Line 2
        // Line 1 and Line 2 on using interchangeably still yields the same infinite loop.
    }
}

class B extends A {
     public void show() {
        System.out.println("Inside B's show cant show private X:");
        // change(8);           Line 3
        super.change(8);    //  Line 4
        // Line 3 and Line 4 on using interchangeably still yields the same infinite loop.
     }
}

public class Main
{
    public static void main(String[] args) {
        B b = new B();
        b.show();
    }
}

输出为:

Inside B's show cant show private X:
Inside B's show cant show private X:
Inside B's show cant show private X:
Inside B's show cant show private X:
Inside B's show cant show private X:
Inside B's show cant show private X:
Inside B's show cant show private X:
... lots of times and then 

at A.change(Main.java:9)
at B.show(Main.java:17)
at A.change(Main.java:9)
at B.show(Main.java:17)
at A.change(Main.java:9)
at B.show(Main.java:17)
at A.change(Main.java:9)
at B.show(Main.java:17)
at A.change(Main.java:9)
at B.show(Main.java:17)
... lots of times

是什么导致这个程序进入这个无限循环,如何避免?

在您的 A class 中,您调用:this.show(),而 this 表示 'this object',这将调用 'this object's show() implementation',并且鉴于 'this object' 实际上是 B 的一个实例,'implementation of show()' 是 B.java 中定义的实例,因此导致无限循环。请注意 show(); 只是 this.show(); 的语法糖 - 难怪这两行会做同样的事情 - 两行 mean 同样的事情。

听起来您的意图不是调用此对象的 show() 方法的实现,而是:此非常中定义的 show() 方法文件.

你不能在 java 中这样做。

你没有什么可以写的(不是 this,也不是 super,也没有别的)说:我想要这个明确的实现。

你当然可以解决这个问题:

public class A {
    public void show() {
        showImpl();
    }

    private static void showImpl() {
        // this method is static.
        // that means it has opted out, entirely, of inheritance.
        System.out.println("Inside A's show showing private X: " + x);
    }

    public void change(int num) {
        this.x = num;
        showImpl();
    }
}

现在您已经解决了问题。对 showImpl 的调用将转到同一个文件中 showImpl 的确切实现,保证每次都如此,因为静态方法不会 'do' 方法的动态查找。