Java 11 - Local-Variable Syntax for Lambda Parameters (JEP 323)

One enhancement in Java 11 covered in JEP 323 is to allow var to be used when declaring the formal parameters of implicitly typed lambda expressions. The goal is to align the syntax of a formal parameter declaration in an implicitly typed lambda expression with the syntax of a local variable declaration.

A lambda expression may be implicitly typed, where the types of all its formal parameters are inferred:

(x, y) -> x.process(y) // implicitly typed lambda expression

Java SE 10 makes implicit typing available for local variables:

var x = new Foo(); for (var x : xs) { ... } try (var x = ...) { ... } catch ...

For uniformity with local variables, Java 11 now allow 'var' for the formal parameters of an implicitly typed lambda expression:

(var x, var y) -> x.process(y) // implicit typed lambda expression

One benefit of uniformity is that modifiers, notably annotations, can be applied to local variables and lambda formals without losing brevity:

@Nonnull var x = new Foo(); (@Nonnull var x, @Nullable var y) -> x.process(y)

Example

x in JEP323LambdaWithoutLocalVar's lambda expression is not declared as var:

JEP323LambdaWithoutLocalVar.java
package com.dariawan.jdk11;

import java.util.Arrays;

public class JEP323LambdaWithoutLocalVar {

    public static void main(String[] args) {

        var arrInteger = new Integer[]{5, 9, 3, 6, 2, 4, 8, 7, 1};
        long cnt = Arrays.stream(arrInteger).filter(
                x -> (x != null && x > 5)).count();
        System.out.println(cnt);
    }
}
                    

JEP323LambdaWithLocalVar using var when declaring x parameters:

JEP323LambdaWithLocalVar.java
package com.dariawan.jdk11;

import java.util.Arrays;
import javax.annotation.Nonnull;

public class JEP323LambdaWithLocalVar {

    public static void main(String[] args) {

        var arrInteger = new Integer[]{5, 9, 3, 6, 2, 4, 8, 7, 1};
        long cnt = Arrays.stream(arrInteger).filter(
                (@Nonnull var a) -> (a != null && a > 5)).count();
        System.out.println(cnt);
    }
}
                    

We also apply @Nonnull annotation to local variables x.

  • @Nonnull – The compiler can determine cases where a code path might receive a null value, without ever having to debug a NullPointerException.

The annotations is useful for your IDE to give you hints that it's unnecessary to test for null, since compiler expecting non null value.

JEP 323: Lambda Expression With Local var

Lambda Expression With Annotated Local var (Netbeans 10)

Beside your IDE giving you hints, I can think further advantages:

  • Static code analysis tools can test the same as your IDE (example: FindBugs, PMD Tools)
  • Or even used by code quality platform (example: SonarQube)
  • You can use AOP to check this assertions

So it can help to create code that is more maintainable and less error-prone. At the end, it's about code quality.