Skip to content

Instantly share code, notes, and snippets.

@squid314
Last active October 7, 2019 01:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save squid314/946b664880632abf09a6f027c76f3a97 to your computer and use it in GitHub Desktop.
Save squid314/946b664880632abf09a6f027c76f3a97 to your computer and use it in GitHub Desktop.
A lambda does not close over local variables it does not reference.
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;
}
};
}
}
}
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