jdk 10/11 local variable type inference
Reserved type name 'var' was introduced to be used instead of explicit type declaration, where type can be deduced...

Official documentation
Style guidelines
This lesson includes local variable type inference from JDK 10 and local variable syntax for lambda parameters (JDK 11). Reserved type name ‘var’ was introduced to be used instead of the explicit type declaration, where type can be deduced.
How to use ‘var’?
1) local variable declarations with initializer;
var users = new ArrayList<String>();
users.add("Tom");
users.add("Jim");
2) enhanced for-loop
for (var user : users) {
System.out.println(user);
}
3) traditional for-loop
for (var i = 0; i < users.size(); i++) {
System.out.println(users.get(i));
}
4) try with resources
try (var scanner = new Scanner(new File("src/main/resources/example.txt"))) {
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
5) with anonymous classes
var x = new Runnable() {
@Override
public void run() {
System.out.println("var is allowed with anonymous classes");
}
};
x.run();
6) casting lambda expressions to intersection types
public static void varIsAllowedInCastingLambdaExpressionsToIntersectionTypes() {
var x = (LogSystem & Serializable) () -> System.out.println("implementation");
x.print();
}
How to not use ‘var’?
1) var
cannot be used in catch clauses
catch (var e) {
e.printStackTrace();
}
2) var
not allowed for method type declaration
public static void varNotAllowedForMethodArgumentTypeDeclaration(var illegalVarDeclaration) {
System.out.println(illegalVarDeclaration);
}
3) var
cannot be used to define constructor arguments type
public VarExamples(var x) {
this.x = x;
}
4) var
cannot be used as a method return type
public var varCannotBeUsedAsMethodReturnType() {
return "example";
}
5) var
not allowed to be used as a field type
private var varNotAllowedToBeUsedAsFieldType;
6) var
not allowed as a target type of lambda expression
var serialNumber = (x, y) -> x + "&" + y;
7) null cannot be assigned to var
var x = null;
8) var
cannot be used with array initializer
var x = {"one", "two"};
‘var’ is not a keyword, it is reserved type name, hence:
1) you can use var as a variable name. you cannot do it with keywords.
private final String var ="t";
// private final String class = "";
2) you can use it as a package name;
3) you can use it as a method name
public void var() {}
4) we cannot create a class name with a name var
// public static class var {}
5) we cannot name interface as ‘var’
public interface var {}
Java 11
Java 11 allows using var in lambda expressions.
- (var x, var y) -> x + “-“ + y … is the same as … (x, y) -> x + “-“ + y
- This change is a further enhancement of var usage in java, that was introduced in jdk 10.
- var allows us usage of annotations (@NotNull for example).
- var cannot be mixed with no var.
- var cannot be mixed with explicitly typed parameters (e.i. int)
- var should be used for all lambda formal parameters not be used at all.
public static void combineSerialNumberAndPrint(String classification, String no) {
BiFunction<String, String, String> serialNumber = (var x, var y) -> x + "-" + y;
System.out.println(serialNumber.apply(classification, no));
}
lombok alternative: ‘var’ and ‘val’
Explicit import required:
import lombok.var;
Pitfalls
Be careful using var with diamonds <>. Type inference for generic methods relies on the target type (what on the left of ‘=’). For ‘var inferredQueue’ inferred type is PriorityQueue
public void varPitfallsWithDiamonds() {
PriorityQueue<String> queue = new PriorityQueue<>();
System.out.println(queue);
var inferredQueue = new PriorityQueue<>();
System.out.println(inferredQueue);
Comparator<String> comparator = (o1, o2) -> 0;
var correctInferredQueue = new PriorityQueue<>(comparator);
System.out.println(correctInferredQueue);
}
It is a common practice in java to construct a concrete instance and assign it to an interface type. If ‘var’ is used, the inferred type is a concrete instance, instead of an interface.
public void varPitfallsWithList() {
List<String> users = new ArrayList<>();
System.out.println(users);
var workers = new ArrayList<>();
System.out.println(workers);
}
With a numeric type on the left, a type might be widened or narrowed to types other than int. With ‘var’ type is always int.
public void pitfallWithNumericLiterals() {
byte point = 0;
short hash = 0x77f;
long id = 2;
var x = 34;
}