Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java : explain Closure in this code

Tags:

java

closures

I understand closure and have applied in some language such as Python and SML. Nevertheless, when I read wikipedia about closure in Java (of course, just 8 version), I don't understand difference if Java supports closure or not in their example.

Those code I copy from Wikipedia : Closure

The java code without closure :

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

And if Java supports closure, the code will looks like:

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

So, my question is : if Java supports closure, which special thing in second code ? I really don't see main difference between two code.

Please tell me this point.

thanks :)

like image 411
hqt Avatar asked Feb 09 '13 03:02

hqt


2 Answers

The point is that they are not really so different functionally:

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

is equivalent to a new class instance of Runnable with an equivalent implementation of the run() method. You replace a lot of "boiler-plate" code with a simple lambda function.

Using the lambda, your code becomes much more expressive, concise, easier to write, and very readable. And that's just where the benefits start, once you enter the world of closures and lambda functions.

like image 171
Richard Sitze Avatar answered Oct 09 '22 05:10

Richard Sitze


The difference is that:

  • in the first case you are declaring an anonymous class and creating an instance, but
  • in the second case there is no class and no instance. Instead, there is a lambda ... effectively an anonymous function.

They achieve the same end, but the lambda syntax is certainly more light-weight.

However, a lambda can only access local variables in the scope in which it is declared if they are final (or effectively final); see 15.27.2 in JSR-000335 review draft #2. So you could argue that Java lambdas are not full closures.

But the JSR-000335 spec does imply that lambdas are NOT anonymous classes. And this and super in a lambda body have a different meaning that they do in a method.

The spec describes lambdas (at one point) as being implemented using "synthetic classes", and states that an instance of the synthetic classes can be reused when appropriate as a compilation optimization. (By contrast, the compiler would not be allowed to make that optimization for an anonymous class.) This optimization means that lambdas are likely to perform better than the equivalent coded using anonymous classes.

like image 23
Stephen C Avatar answered Oct 09 '22 04:10

Stephen C