为什么必须在 Java 中创建 ActionListeners 的实例?

Why do you have to create instances of ActionListeners in Java?

当我创建一个 ActionListener 时,例如。对于按钮,我必须创建 ActionListener 的实例。特别是当我有多个按钮时,我会说

button1.addActionListener(new MyOwnListener());

在代码的其他地方我只是创建了另一个实例

button2.addActionListener(new MyOwnListener());

因为我懒得用同一个实例两次

但是,创建这么多无用的实例,这不是在浪费space吗?为什么 Listener 不能是静态的?

MyOwnListener.actionPerformed(event);

而不是

yetAnotherInstance.actionPerformed(event);

我无法想象这是行不通的情况。您无需区分相同 class 的 Listener,您只需创建实例即可。

我希望你能明白我想说的,即使我的英语不好。

  1. 如果您创建一个静态侦听器方法,您如何告诉您的按钮在发生事件时调用该方法?没有像函数指针这样的东西可以传递给按钮的 addActionListener(...) 方法。 (从java8开始就有这种事,那是另外一回事了)

  2. 在大多数情况下,不同的按钮有不同的含义,应该执行不同的代码。

  3. 将所有代码都放在静态方法中与面向对象编程无关。这不一定是坏事,但证明你做错了...

  4. 如果您担心同一个监听器的实例太多,请分享它们!懒惰不是糟糕编程的借口。 (但是如果您共享实例,请确保它们不包含您不想共享的任何状态信息!)

  5. 因为Java8,你可以做:

    button1.addListener(MyOwnListener::actionPerformed); button2.addListener(MyOwnListener::actionPerformed);

开心吗?

可以使用单实例!它只是一团糟,因为它是一个单一的事件处理程序。

示例:

MyOwnListener myOwnListener = new MyOwnListener();
button1.addActionListener(myOwnListener);
button2.addActionListener(myOwnListener);

在这种情况下

public class MyOwnListener implements ActionListener {
     @Override
     public void actionPerformed(ActionEvent e) {
         if(e.getSource() == button1) {
             executeCodeForButton1();
         } else if(e.getSource() == button2) {
             executeCodeForButton2();
         }
     }
}

它有多个按钮变得有点混乱,并且更难重构。

编辑:一个实例和全局对象,单例模式

public class YourFrame extends JFrame {

    JButton button1;
    JButton button2;

    public YourFrame() {
        ...
        button1 = new JButton("Hello");
        button2 = new JButton("World");
        button1.addActionListener(YourOwnListener.INSTANCE);
        button2.addActionListener(YourOwnListener.INSTANCE);
    }

    public static enum YourOwnListener implements ActionListener {
        INSTANCE;

        private YourOwnListener() {}

        public void actionPerformed(ActionEvent e) {
            if(e.getSource() == button1) {
                executeMethodForButton1();
            } else if(e.getSource() == button2) {
                executeMethodForButton2();
            }
        }
    }
}

不过这也是在用实例。这是因为他们正在实施 Observer 模式。侦听器实现表示执行操作时运行的函数,这类似于 Javascript 中的函数或 C/C++ 中的函数指针。