8

私はクロージャを理解しており、Python や SML などの言語で適用したことがあります。それにもかかわらず、Java のクロージャについてウィキペディアを読んだとき (もちろん、8 バージョンのみ)、Java がクロージャをサポートしているかどうかの違いが、その例ではわかりません。

ウィキペディアからコピーしたコード : Closure

クロージャのない 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();
  }
}

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();
  }
}

だから、私の質問は次のとおりです。Javaがクロージャーをサポートしている場合、2番目のコードのどの特別なことですか? 2つのコードの主な違いは本当にわかりません。

この点を教えてください。

ありがとう :)

4

3 に答える 3

4

重要なのは、機能的にはそれほど違いがないということです。

() -> {
    calculate(uri);
    result = result + 10;
}

run()メソッドの同等の実装を持つRunnableの新しいクラスインスタンスと同等です。多くの「ボイラープレート」コードを単純なラムダ関数に置き換えます。

ラムダを使用すると、コードがはるかに表現力豊かで簡潔になり、記述しやすくなり、非常に読みやすくなります。そして、クロージャとラムダ関数の世界に入ると、そこからメリットが始まります。

于 2013-02-09T04:01:35.547 に答える
2

違いは次のとおりです。

  • 最初のケースでは、匿名クラスを宣言してインスタンスを作成していますが、
  • 2 番目のケースでは、クラスもインスタンスもありません。代わりに、ラムダがあります...事実上無名関数です。

どちらも同じ目的を達成しますが、ラムダ構文は確かに軽量です。

ただし、ラムダは、宣言されているスコープ内のローカル変数にのみアクセスできますfinal(または実質的に最終的な場合)。JSR-000335 レビュー ドラフト #2 の 15.27.2 を参照してください。したがって、Java ラムダは完全なクロージャではないと主張できます。

しかし、JSR-000335 仕様は、ラムダが匿名クラスではないことを暗示しています。そしてthissuperラムダ本体では、メソッドで行うのとは異なる意味を持ちます。

仕様では、ラムダは (ある時点で) 「合成クラス」を使用して実装されていると説明されており、コンパイルの最適化として適切な場合に合成クラスのインスタンスを再利用できると述べています。(対照的に、コンパイラは、匿名クラスに対してそのような最適化を行うことはできません。) この最適化は、匿名クラスを使用してコード化された同等のコードよりも、ラムダ式の方がパフォーマンスが優れて いる可能性が高いことを意味します。

于 2013-02-09T03:59:55.063 に答える