0

呼び出されたメソッドがあり、クリックされたときにメソッドを呼び出すようにしJButtonます。もちろん、古いアプローチを使用してそれを行うことができます。saveButtonsave

    saveButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            save();
        }
    });

しかし、今日はメソッド参照などの新しい Java 8 機能を使用したいと考えています。なぜ

    saveButton.addActionListener(this::save);

うまくいかない?メソッド参照を使用してどのように行われますか?

4

2 に答える 2

3

メソッドactionPerformed(ActionEvent e)には単一のパラメーターが必要eです。メソッド参照を使用する場合は、メソッドに同じ署名が必要です。

private void myActionPerformed(ActionEvent e) {
    save();
}

次に、メソッド参照を使用できます。

saveButton.addActionListener(this::myActionPerformed);

または、代わりにラムダを使用できます (通知eパラメーター):

saveButton.addActionListener(e -> save());
于 2014-10-11T22:14:25.000 に答える
2

ラムダを使用できます:

saveButton.addActionListener((ActionEvent e) -> save());

これが可能なのは、ActionListener が関数型インターフェースであるためです (つまり、メソッドが 1 つしかない)。関数型インターフェースは、抽象メソッドを 1 つだけ含む任意のインターフェースです。ラムダは呼び出しの省略形です。

Lambda を使用する代わりに、クラスに問題のインターフェイス (またはインスタンス変数を持つ他のクラス) を実装させることにより、メソッド参照を使用できます。完全な例を次に示します。

public class Scratch implements ActionListener {

    static JButton saveButton = new JButton();

    public void save(){};

    public void contrivedExampleMethod() {

        saveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                save();
            }
        });

        // This works regarless of whether or not this class
        // implements ActionListener, LAMBDA VERSION
        saveButton.addActionListener((ActionEvent e) -> save());

        // For this to work we must ensure they match
        // hence this can be done, METHOD REFERENCE VERSION
        saveButton.addActionListener(this::actionPerformed);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        save();
    }
}

もちろん、これは単なる不自然な例ですが、正しいメソッドを渡すか、ラムダを使用して正しい内部クラス (のような) 実装を作成していると仮定すると、どちらの方法でも実行できます。動的な性質のために、ラムダの方法はあなたが望むものを達成するという点でより効率的だと思います. それが結局のところ、彼らがそこにいる理由です。

于 2014-10-11T22:03:46.907 に答える