Using method references

有些话、适合烂在心里 提交于 2019-12-08 10:44:19

问题


I've got a JButtoncalled saveButton and want it to call the save method when it is clicked. Of course we can do it using the old approach:

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

But today I want to use new Java 8 features like method references. Why does

    saveButton.addActionListener(this::save);

not work? How is it done using method references?


回答1:


Method actionPerformed(ActionEvent e) requires single parameter e. If you want to use a method reference, your method must have the same signature.

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

Then you can use method reference:

saveButton.addActionListener(this::myActionPerformed);

Or you can use lambda instead (notice e parameter):

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



回答2:


You can use a lambda:

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

This can be done because the ActionListener is a functional interface (i.e. there is only one method). A functional interface is any interface that contains only one abstract method. Lambdas are shorthand for the call.

Alternatively to using the Lambda you can use a method reference by having your class implement the interface in question (or some other class with an instance variable). Here is a full example:

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();
    }
}

This of course is just a contrived example but it can be done either way assuming you are passing the correct method or creating the correct inner class (like) implementation using Lambdas. I think the lambda way is more efficient in terms of achieving what you want because of the dynamic nature. That is after all why they are there.



来源:https://stackoverflow.com/questions/26319537/using-method-references

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!