4. var — Local Variable Type Inference
var lets the compiler infer the type of a local variable from its initializer, reducing boilerplate — but it's not dynamic typing and has strict limits.
Explanation
var (introduced in Java 10 via JEP 286) tells the compiler to infer the static type of a local variable from its initializer. It is purely a compile-time feature — the bytecode is identical to explicitly typed code. Java remains statically typed; var just removes redundant type declarations.
Restrictions: var can only be used for local variables with initializers, for-loop variables, and try-with-resources variables. It cannot be used for fields, method parameters, return types, or lambda parameters (except in Java 11's (var x, var y) -> ... syntax for annotating lambda params).
var hurts readability when the inferred type is not obvious from the right-hand side. var x = process(data); — what is x? Use it when the type is evident (var list = new ArrayList<String>()) and avoid it when it obscures intent.
Example
import java.util.ArrayList;
import java.util.HashMap;
public class VarDemo {
public static void main(String[] args) {
// Type is obvious from the right-hand side: good use
var names = new ArrayList<String>();
names.add("Alice");
names.add("Bob");
// for-loop: common and readable
for (var name : names) {
System.out.println(name.toUpperCase()); // compiler knows name is String
}
// Also works with primitive inference
var count = 42; // inferred as int
var pi = 3.14; // inferred as double
// Map: still clear because the RHS spells out the type
var map = new HashMap<String, Integer>();
map.put("Alice", 1);
// BAD: type not obvious — avoid var here
// var result = compute(); // what is result?
System.out.println("Count: " + count + ", Pi: " + pi);
System.out.println("Names: " + names);
}
}Sources
- https://openjdk.org/jeps/286 — JEP 286: Local-Variable Type Inference
- https://openjdk.org/projects/amber/guides/lvti-style-guide — Style guide for var