Difference between using a lambda and an anonymous inner interface implementation [message #1823384] |
Wed, 25 March 2020 22:21 |
Hallvard Traetteberg Messages: 673 Registered: July 2009 Location: Trondheim, Norway |
Senior Member |
|
|
I've just experience a very strange problem concerning SWT listeners implemented using a lambda. Replacing it with an old-fashioned instance of an anonymous inner interface implementation fixed the problem, but the behaviour is supposed to be the same isn't it!?
The case is a form with a set of Button instances that I create in a loop. For each of them I add an SWT Listener that closes over a variable referring to the new Button. All the buttons are also stored in an array references by a field. Here's the program structure:
for (int i = 0; i < options.size(); i++) {
final Button button = new Button(parent, SWT.RADIO);
button.addListener(SWT.Selection, event -> {
...
});
this.buttons[i] = button;
}
The first time the selection event is triggered all is fine, inside the listener's body the button variable refers to the same button as in the buttons array and the event's widget field. However, in later instances of the form, with a new set of buttons, this is not the case! The closed over button variable refers to a button from an earlier for that's disposed, and it's not one of the buttons in the buttons array. When I look down the stack, I see that the listener activated by SWTs event loop is not the same one I see on the top of the stack, it looks more like the correct one. One thing I notice is that the listener is not identified by the normal inner class name ala someclass$1, instead it is a some large number. I assume this is because the lambda is compiled into dynamic invoke or something, so it just looks different.
Anyway, I change the above code to
for (int i = 0; i < options.size(); i++) {
final Button button = new Button(parent, SWT.RADIO);
button.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
...
}
});
this.buttons[i] = button;
}
which if I understand it correctly should be equivalent, and now everything works as expected! The button variable closed over is the one I expect, the event object's widget field refers to the same Button instance as button refers to, the stack looks normal etc.
Anyone knows what's happening? Am I completely mistaken in how the lambda expression is supposed to be equivalent to the instance of the anonymous interface implementation?
BTW, I'm using SWT from 2018, version 3.107.20160611 and running on SE 8 [1.8.0_51]
[Updated on: Wed, 25 March 2020 22:25] Report message to a moderator
|
|
|
|
Powered by
FUDForum. Page generated in 0.03792 seconds