Java:解释此代码中的Closure

hqt*_*hqt 8 java closures

我理解闭包并已经应用了一些语言,如Python和SML.然而,当我阅读维基百科关于Java中的闭包(当然,只有8个版本)时,如果Java在他们的示例中支持闭包,我不明白区别.

我从维基百科复制的那些代码:关闭

没有闭包的java代码:

class CalculationWindow extends JFrame {
  private volatile int result;
  ...
  public void calculateInSeparateThread(final URI uri) {
    // The expression "new Runnable() { ... }" is an anonymous class implementing the 'Runnable' interface.
    new Thread(
      new Runnable() {
        void run() {
          // It can read final local variables:
          calculate(uri);
          // It can access private fields of the enclosing class:
          result = result + 10;
        }
      }
    ).start();
  }
}
Run Code Online (Sandbox Code Playgroud)

如果Java支持闭包,代码将如下所示:

class CalculationWindow extends JFrame {
private volatile int result;
  ...
  public void calculateInSeparateThread(final URI uri) {
    // the code () -> { /* code */ } is a closure
    new Thread(() -> {
        calculate(uri);
        result = result + 10;
    }).start();
  }
}
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是:如果Java支持闭包,第二个代码中哪个特殊的东西?我真的没有看到两个代码之间的主要区别.

请告诉我这一点.

谢谢 :)

Ste*_*n C 2

不同之处在于:

  • 在第一种情况下,您声明一个匿名类并创建一个实例,但是
  • 在第二种情况下,没有类也没有实例。相反,有一个 lambda……实际上是一个匿名函数。

它们达到了相同的目的,但 lambda 语法肯定轻量级。

final然而,如果局部变量是(或实际上是最终的),则lambda 只能访问其声明范围内的局部变量;请参阅 JSR-000335 审查草案 #2 中的 15.27.2。所以你可能会说 Java lambda 不是完全闭包。

但 JSR-000335 规范确实暗示 lambda 不是匿名类。并且thissuper在 lambda 主体中的含义与它们在方法中的含义不同。

该规范将 lambda(在某一时刻)描述为使用“合成类”实现,并指出合成类的实例可以在适当的时候重用作为编译优化。(相比之下,不允许编译器对匿名类进行这种优化。)这种优化意味着 lambda 可能使用匿名类编写的等效代码执行得更好。