1

I implemented history by letting my forms to implement reconstructor, which is a lambda-returning method. It can be as simple as

@Override protected Supplier<MpxForm> reconstructor() {
    return () -> new MyForm1();
}

or more complicated like e.g.,

@Override protected Supplier<MpxForm> reconstructor() {
    State currentState = this.currentState;
    Set<Item> selectedItems = this.selectedItems;
    return () -> new MyForm2(currentState, selectedItems);
}

None of the lambdas needs access to the enclosing instance. That's important as it allows the form to be garbage collected.

However, with retrolambdas, they get converted to an inner class and as I was told, they use this as a reference to their surrounding class so they have a reference to their parent just like non-static inner classes.

This is unnecessary and IIUIC, retrolambda can do it right:

Lambda expressions are backported by converting them to anonymous inner classes. This includes the optimization of using a singleton instance for stateless lambda expressions to avoid repeated object allocation.

Obviously, the lambda in my first snippet is stateless, nonetheless, it was converted to a class having an instance variable of type MyForm1. The above optimization is missing.

The lambda in my second snippet has two instance variables and needs no reference to the enclosing class, so it could be converted to a nested class like

@RequiredArgsConstructor static class MyForm2$Lambda1 implements Runnable {
    private final State currentState;
    private final Set<Item> selectedItems;

    @Override public void run() {
        return new MyForm2(currentState, selectedItems);
    }
}

Any chance to fix this?

maaartinus
  • 44,714
  • 32
  • 161
  • 320
  • Did you check the converted bytecode? Are you sure this is actually happening? E.g. for static inner classes no this is passed and it's possible retrolambda detects that case. I haven't tested that so I have no idea. – Shai Almog Dec 14 '19 at 03:01
  • @ShaiAlmog There's something wrong on my side. In my real code, `this` was indeed captured, but with a newly created tiny example it works perfectly. Unfortunately, it means that my `reconstructor` is error-prone in this respect, so I'll have to re-thing it. – maaartinus Dec 14 '19 at 19:01

0 Answers0