java.lang.StackOverflowError 关于在 JPanel 中实现 Runnable - Java Swing

java.lang.StackOverflowError on implementing Runnable in a JPanel - Java Swing

我有一个 JPanel 实现了 Runnable 接口和 overrides run() 方法。在我的 JPanel 的构造函数中,我初始化了一个 private class(JPanel) Thread 的实例,它以 new MyPanel 作为参数。 在这条线上,我得到一个 Exception in thread "main" java.lang.WhosebugError.

之后的错误:

    at java.awt.Component.setForeground(Unknown Source)
    at javax.swing.JComponent.setForeground(Unknown Source)
    at javax.swing.LookAndFeel.installColors(Unknown Source)
    at javax.swing.LookAndFeel.installColorsAndFont(Unknown Source)
    at javax.swing.plaf.basic.BasicPanelUI.installDefaults(Unknown Source)
    at javax.swing.plaf.basic.BasicPanelUI.installUI(Unknown Source)
    at javax.swing.JComponent.setUI(Unknown Source)
    at javax.swing.JPanel.setUI(Unknown Source)
    at javax.swing.JPanel.updateUI(Unknown Source)
    at javax.swing.JPanel.<init>(Unknown Source)
    at javax.swing.JPanel.<init>(Unknown Source)
    at javax.swing.JPanel.<init>(Unknown Source)

然后:

    at MyPanel.<init>(MyPanel.java:39)
    at MyPanel.<init>(MyPanel.java:45)

第 39 行是我的 JPanel 构造函数,第 45 行是 class Thread 的初始化代码,即 this.generateBallsThread = new Thread(new MyPanel());

这里只放了与问题相关的代码。

MyPanel.java:

public class MyPanel extends JPanel implements KeyListener,Runnable
{
    private static final long serialVersionUID = 1L;

    private static final Color BACKGROUND_COLOR = Color.WHITE; 
    private static final Color NPC_BALLS_COLOR = Color.RED;

    // The player is an oval
    private int playerRadius = 25;
    private int playerX;
    private int playerY;

    // True - first player position, false - otherwise
    private boolean playerPosition = true;

    // Array of all the balls threads
    private ArrayList<BallThread> balls = new ArrayList<BallThread>();

    private Thread generateBallsThread;

    public MyPanel()
    {
        this.setBackground(MyPanel.BACKGROUND_COLOR);
        this.setFocusable(true);
        this.addKeyListener(this);

        this.generateBallsThread = new Thread(new MyPanel()); // WhosebugError
        generateBallsThread.start();
    }
}

我很困惑。这就是您使用 Runnable 界面的方式,所以 java 想要我做什么?

new MyPanel() 替换为 this。这将停止导致堆栈溢出的无限递归调用

为什么会出现 SO 异常? MyPanel class 的构造函数会创建另一个 MyPanel。这会导致 class 继续创建,直到超出堆栈边界,从而导致堆栈溢出。

由于该行,您的代码将进入无限循环 this.generateBallsThread = 新线程(新我的面板()); ,因为您正在其构造函数中创建 class MyPanel 的对象,它将再次调用相同的构造函数。