【问题标题】:Java, StackOverflowError when extending a class, or instantiating扩展类或实例化时的 Java、StackOverflowError
【发布时间】:2017-02-03 16:32:07
【问题描述】:

好的,一开始,我知道为什么我收到了这个错误,但不知道如何解决它。

我有几个类,一个主类,一个布局类和一个 buttonClick 类。

问题出在 buttonClick 类中:我的布局类中有一些变量必须在 buttonClick 类中使用。

这是我的布局类:

public class Layout extends JPanel {
    public JButton BTN_werpen;

    public Layout{
        BTN_werpen = new JButton("Werpen");
        BTN_werpen.setBounds(465, 10, 80, 30);
        BTN_werpen.addActionListener(new WerpButton());
        P_velden.add(BTN_werpen);
    }

当然,这不是完整的课程,但它是你需要知道的一切。

我有我的“WerpButton”actionListner 类:

public class WerpButton extends Layout implements ActionListener {
    BTN_werpen.setEnabled(false);
}

同样,这还不是全部,但是当我在这里使用代码时它已经失败了。而且我知道它为什么会失败:那是因为当 Layout 类被扩展时,构造函数被调用,它将创建一个新对象,该对象触发 WerpButton 类,然后调用 Layout 类,依此类推。它基本上变成了一个循环。

现在,我的问题是:

我该如何解决这个问题?

我已经尝试了很多, 喜欢不扩展它,只使用Layout layout = new Layout(); 然后在我的代码中使用layout.BTN_werpen,但这也不起作用。

【问题讨论】:

  • 你有一个循环依赖。每个子类型都会隐式调用父类的构造函数。
  • 是的,我知道。但是我该如何解决它,以便我可以在我的其他课程中使用BTN_werpen

标签: java swing stack-overflow


【解决方案1】:
public class WerpButton extends Layout

因此,您创建了新的WerpButton(),本质上称为new Layout()

public Layout() {
    ...
    BTN_werpen.addActionListener(new WerpButton());
    ...
}

再次调用new WerpButton... 循环重复


为什么ActionListener 的名字叫anything-“Button”? (当然,除非在按钮类本身上实现)。

换句话说,你为什么要在 Layout 上实现 ActionListener?

您的意思是扩展JButton 而不是Layout

public class WerpButton extends JButton implements ActionListener {
    public WerpButton() {
        this.addActionListener(this);
    }

    @Override
    public void onActionPerformed(ActionEvent e) {
        this.setEnabled(false);
    }
}

此外,如果你有一个单独的类文件,这将不会起作用

public class WerpButton extends Layout implements ActionListener {
    BTN_werpen.setEnabled(false); // 'BTN_werpen' can't be resolved. 
}

您可以尝试另一种方式 - 布局实现侦听器。这样你就不需要一个单独的类来严格处理按钮事件。

public class Layout extends JPanel implements ActionListener {
    public JButton BTN_werpen;

    public Layout() {
        BTN_werpen = new JButton("Werpen");
        BTN_werpen.setBounds(465, 10, 80, 30);
        BTN_werpen.addActionListener(this);
        P_velden.add(BTN_werpen);
    }

    @Override
    public void onActionPerformed(ActionEvent e) {
        if (e.getSource() == BTN_werpen) {
            // handle click
            BTN_werpen.setEnabled(false);
        }
    }

【讨论】:

  • 是的,我知道。我已经这样做了,但我的问题是我得到了一个有 500 行的类,这是我不喜欢的。布局类已经是 281 行,每个按钮都像 80-120 行。所以我认为需要将按钮放在单独的类中。
  • 这是意见和代码组织的问题。当然,您可以将 Button 作为一个单独的类。将 ActionListener 分开并没有真正的意义,因为它们经常需要访问它所附加的类的其他变量
  • @LuukWuijster 你的问题是你扩展了Layout,而你可能打算扩展JButton
  • Why does an ActionListener have the name anything-"Button"。这句话总结了我多年来的感受。停止在所有组件上实现 ActionListener!
  • @BrandonIbbotson 我同意。来自我的 Android 学习 - 命名 xActivity、yFragment、zService 总是,没有例外 :)
猜你喜欢
  • 1970-01-01
  • 2013-07-04
  • 2021-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多