With reference to this question -
How does `this` reference to an outer class escape through publishing inner class instance?
If we replace the anonymous class with the lambda or the method reference why and how this code is going to behave?
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(e -> doSomething(e));
}
}
Technically there is not much of a difference between creating an anonymous inner class or using a lambda. Lambdas are more of less just syntax candy to make something Java was capable of doing all the time more prominent, accessible and less error prone. That is your code is subject to the same race condition described in the question you referred to and its answer.
With the given code construct you got no guarantee that the instance of ThisEscape is properly created before doSomething is called.
Read the javaspecialists.eu newsletter that is linked in this answer to understand under what circumstances that might be problematic.
In the original question the code
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
is problematic because the object have been registered in the constructor and then may be used by the event managing system while not being fully constructed. In fact, this is dangerous only if doSomething access something external to the ThisEscape instance.
And this is the same with your lambda "equivalent"
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(e -> doSomething(e));
}
}
But don't be fooled, anonymous inner classes are not strictly equivalent to lambdas... this refers to the current instance in case of anonymous inner class but refers to the enclosing instance of the lambda (this is in the closure of the lambda) :
interface doable {
public void doIt();
}
public class Outer {
public Outer() {
doable d1 = new doable() {
public void doIt() {
System.out.println(this);
}
};
d1.doIt();
doable d2 = ()->System.out.println(this);
d2.doIt();
}
public static void main(String []argv) {
new Outer();
}
}
produces something like :
Outer$1@3764951d
Outer@3cd1a2f1
The second line clearly shows that a lambda is not an instance of any class, it is not an object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With