Last active
October 7, 2019 01:09
-
-
Save squid314/946b664880632abf09a6f027c76f3a97 to your computer and use it in GitHub Desktop.
A lambda does not close over local variables it does not reference.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.ref.WeakReference; | |
import java.util.function.Supplier; | |
public class App { | |
public static void main(String[] args) { | |
System.out.println("Using lambda, does NOT hold on to unreferenced local variable:"); | |
Object strong0 = new Object(); | |
Supplier<WeakReference<Object>> s0 = lambda(strong0); | |
System.out.println(strong0); | |
System.out.println(s0.get()); | |
System.out.println(s0.get().get()); | |
System.out.println("\nnulling the strong reference"); | |
strong0 = null; | |
System.out.println(strong0); | |
System.out.println(s0.get()); | |
System.out.println(s0.get().get()); | |
System.out.println("\nrequesting a garbage collect"); | |
System.gc(); | |
System.out.println(strong0); | |
System.out.println(s0.get()); | |
System.out.println(s0.get().get()); | |
System.out.println("\n\n\nUsing anon class, does NOT hold on to unreferenced local variable:"); | |
Object strong1 = new Object(); | |
Supplier<WeakReference<Object>> s1 = anon(strong1); | |
System.out.println(strong1); | |
System.out.println(s1.get()); | |
System.out.println(s1.get().get()); | |
System.out.println("\nnulling the strong reference"); | |
strong1 = null; | |
System.out.println(strong1); | |
System.out.println(s1.get()); | |
System.out.println(s1.get().get()); | |
System.out.println("\nrequesting a garbage collect"); | |
System.gc(); | |
System.out.println(strong1); | |
System.out.println(s1.get()); | |
System.out.println(s1.get().get()); | |
System.out.println("\n\n\nUsing lambda, does NOT hold on to unreferenced wrapping class instance:"); | |
Object strong2 = new Object(); | |
ReferenceFactory factory2 = new ReferenceFactory(); | |
WeakReference<ReferenceFactory> weak2 = new WeakReference<>(factory2); | |
Supplier<Object> s2 = factory2.lambda(strong2); | |
System.out.println(strong2); | |
System.out.println(factory2); | |
System.out.println(weak2); | |
System.out.println(weak2.get()); | |
System.out.println(s2.get()); | |
System.out.println("\nnulling the factory reference (the wrapping this of the lambda)"); | |
factory2 = null; | |
System.out.println(strong2); | |
System.out.println(factory2); | |
System.out.println(weak2); | |
System.out.println(weak2.get()); | |
System.out.println(s2.get()); | |
System.out.println("\nrequesting a garbage collect"); | |
System.gc(); | |
System.out.println(strong2); | |
System.out.println(factory2); | |
System.out.println(weak2); | |
System.out.println(weak2.get()); | |
System.out.println(s2.get()); | |
System.out.println("\n\n\nUsing anon class, DOES hold on to unreferenced wrapping class instance:"); | |
Object strong3 = new Object(); | |
ReferenceFactory factory3 = new ReferenceFactory(); | |
WeakReference<ReferenceFactory> weak3 = new WeakReference<>(factory3); | |
Supplier<Object> s3 = factory3.anon(strong3); | |
System.out.println(strong3); | |
System.out.println(factory3); | |
System.out.println(weak3); | |
System.out.println(weak3.get()); | |
System.out.println(s3.get()); | |
System.out.println("\nnulling the factory reference (the wrapping this of the lambda)"); | |
factory3 = null; | |
System.out.println(strong3); | |
System.out.println(factory3); | |
System.out.println(weak3); | |
System.out.println(weak3.get()); | |
System.out.println(s3.get()); | |
System.out.println("\nrequesting a garbage collect"); | |
System.gc(); | |
System.out.println(strong3); | |
System.out.println(factory3); | |
System.out.println(weak3); | |
System.out.println(weak3.get()); | |
System.out.println(s3.get()); | |
} | |
private static <T> Supplier<WeakReference<T>> lambda(T strong) { | |
WeakReference<T> weak = new WeakReference<>(strong); | |
return () -> weak; | |
} | |
private static <T> Supplier<WeakReference<T>> anon(T strong) { | |
WeakReference<T> weak = new WeakReference<>(strong); | |
return new Supplier<WeakReference<T>>() { | |
@Override | |
public WeakReference<T> get() { | |
return weak; | |
} | |
}; | |
} | |
private static final class ReferenceFactory { | |
public <T> Supplier<T> lambda(T strong) { | |
return () -> strong; | |
} | |
public <T> Supplier<T> anon(T strong) { | |
return new Supplier<T>() { | |
@Override | |
public T get() { | |
return strong; | |
} | |
}; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Using lambda, does NOT hold on to unreferenced local variable: | |
java.lang.Object@4dcbadb4 | |
java.lang.ref.WeakReference@4e515669 | |
java.lang.Object@4dcbadb4 | |
nulling the strong reference | |
null | |
java.lang.ref.WeakReference@4e515669 | |
java.lang.Object@4dcbadb4 | |
requesting a garbage collect | |
null | |
java.lang.ref.WeakReference@4e515669 | |
null | |
Using anon class, does NOT hold on to unreferenced local variable: | |
java.lang.Object@17d10166 | |
java.lang.ref.WeakReference@1b9e1916 | |
java.lang.Object@17d10166 | |
nulling the strong reference | |
null | |
java.lang.ref.WeakReference@1b9e1916 | |
java.lang.Object@17d10166 | |
requesting a garbage collect | |
null | |
java.lang.ref.WeakReference@1b9e1916 | |
null | |
Using lambda, does NOT hold on to unreferenced wrapping class instance: | |
java.lang.Object@504bae78 | |
App$ReferenceFactory@3b764bce | |
java.lang.ref.WeakReference@759ebb3d | |
App$ReferenceFactory@3b764bce | |
java.lang.Object@504bae78 | |
nulling the factory reference (the wrapping this of the lambda) | |
java.lang.Object@504bae78 | |
null | |
java.lang.ref.WeakReference@759ebb3d | |
App$ReferenceFactory@3b764bce | |
java.lang.Object@504bae78 | |
requesting a garbage collect | |
java.lang.Object@504bae78 | |
null | |
java.lang.ref.WeakReference@759ebb3d | |
null | |
java.lang.Object@504bae78 | |
Using anon class, DOES hold on to unreferenced wrapping class instance: | |
java.lang.Object@484b61fc | |
App$ReferenceFactory@45fe3ee3 | |
java.lang.ref.WeakReference@4cdf35a9 | |
App$ReferenceFactory@45fe3ee3 | |
java.lang.Object@484b61fc | |
nulling the factory reference (the wrapping this of the lambda) | |
java.lang.Object@484b61fc | |
null | |
java.lang.ref.WeakReference@4cdf35a9 | |
App$ReferenceFactory@45fe3ee3 | |
java.lang.Object@484b61fc | |
requesting a garbage collect | |
java.lang.Object@484b61fc | |
null | |
java.lang.ref.WeakReference@4cdf35a9 | |
App$ReferenceFactory@45fe3ee3 | |
java.lang.Object@484b61fc |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment