首页 > 解决方案 > java方法覆盖中的奇怪无限循环

问题描述

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

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

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

标签: javainheritanceoverriding

解决方案


在您的A班级中,您调用:this.show(),并且 asthis表示“此对象”,这将调用“此对象的 show() 实现”,并且鉴于“该对象”实际上是 B 的一个实例,“ show() 的实现” ' 是 中定义的B.java,因此导致无限循环。请注意,这show();只是语法糖this.show();——难怪这两行会做同样的事情——这两行的意思是一样的。

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

你不能在java中做到这一点。

没有什么可以写的(notthis和 not 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 的确切实现,因为静态方法不会“执行”该方法的动态查找。


推荐阅读