Anonymous class receiving a value through a function

Asked

Viewed 34 times

2

Guys, here’s the thing, I just came across a situation that I didn’t quite understand how it works.

Some objects such as the components in the Java Swing, or any type of frameworks objects that have events, it is usually possible to add a System for the programmer to add a method with its own action to that event, correct? In Java is an interface as a parameter of a function such as addeventlistener(Eventlistener).

What happens is that when the developer wants to associate a value to this Software, before making this addition, he can create a class that implements the interface, and then create the fields that he wants and manipulate them in their way in the implementation of the abstract methods of the interface, as the example below:

//Interface para o evento de uma ação de componentes do Swing do Java
public interface ActionListener extends EventListener {

    /**
     * Invoked when an action occurs.
     * @param e the event to be processed
     */
    public void actionPerformed(ActionEvent e);

}

It would be possible to associate some value to manipulate like this:

public class MyActionListener implements ActionListener {

    private MeuObjeto objeto;

    public MyActionListener(MeuObject objeto) {
        this.objeto = objeto;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //ação personalizada com manipulação do objeto recebido aqui
    }
}

And then you could use the class with the interface implementation:

button.addActionListener(new MyActionListener(objeto));

But I did a test in a different way, creating a function that returns an anonymous class from that interface, without creating attributes, type:

    private ActionListener criarActionListener(Long id) {
        return new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //Ação com o parâmetro id passado da função aqui
            }
        };
    }

and then I could pass my Istener like this:

button.addEventListener(criarActionListener(id));

The purpose would be for example, to associate the id of an object of a list or a database, and when performing the action of the button or any other component that fits this model, I in this action can recover the exact object by the id or something like that. And what happens is that this way works, and the id is associated, but the class is anonymous and doesn’t have an id field explicitly added inside it, and it still works, how? I don’t understand how the anonymous class can keep this value that was actually passed by a function without actually associating to some variable in the class field.

  • I also don’t understand the details, but I know that before Java 8 this parameter id needed to be declared as final (that is, there should be some kind of substitution for the constant value that was fixed wherever it was used when the anonymous class was built) and from Java 8 onwards no longer needs (but the effect is the same). Note that declare the anonymous class directly where it will be used and use the id it gives the same result.

  • 1

    @Piovezan Does not need the variable to have the modifier final, it can be "effectively final": https://docs.oracle.com/javase/specs/jls/se15/html/jls-4.html#jls-4.12.4

  • 1

    @hkotsubo That’s what I meant by "the effect is the same". Before Java 8 had to be explicitly final as you certainly know :) https://stackoverflow.com/q/4732544/2241463

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.