Closures in Java

元气小坏坏 提交于 2020-01-23 13:12:42

问题


This example is a simulation of closures in JavaScript (I don't know JS):

public class Lambda {

    public static void main(String[] args) {
        Supplier generator = Lambda.generator();
        System.out.println(generator.get());
        System.out.println(generator.get());
        System.out.println(generator.get());
    }

    static Supplier<Integer> generator() {
        Integer arr[] = {0};
        return () -> ++arr[0];
    }
}

The output is 1 2 3. Usually the lifespan of local method variables is limited by the method execution time. But in this case the reference to arr[] is stored somewhere. So where is it stored and what's under the hood?


回答1:


The Java Language Specification (§15.27.4) says:

The value of a lambda expression is a reference to an instance of a class with the following properties:

  • The class implements the targeted functional interface type ...

So the lambda defines a class, much like an anonymous class declaration does, and the lambda expression results in a reference to an instance of that class. The reference to arr is held by a synthetic final field belonging to that instance.


Here's an example using reflection in the JShell REPL, to demonstrate a lambda with a synthetic field:

> class A { static Runnable a(int x) { return () -> System.out.println(x); } }
| created class A

> Runnable r = A.a(5);
r ==> A$$Lambda$15/1476394199@31ef45e3

> import java.lang.reflect.Field;

> Field f = r.getClass().getDeclaredFields()[0];
f ==> private final int A$$Lambda$15/1476394199.arg$1

> f.setAccessible(true);

> f.get(r)
$6 ==> 5


来源:https://stackoverflow.com/questions/59444395/closures-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!