Java 16: var, Type Inference & Lambdas
easy⏱ 5 mincoursejava
Where var works
Local variables with initializers only — var list = new ArrayList<String>(); works, var x; doesn't (no RHS to infer from). Not allowed for: method parameters, method return types, fields, or uninitialized locals. var is a soft keyword — var as a variable name still works.
var list = new ArrayList<String>(); // List<String>
var stream = Files.lines(path); // Stream<String>
for (var line : lines) { ... } // var for-each
When var hurts readability
var result = compute(); — what's result? A List, a Future, a primitive? Without a good variable name, var hides information. The official guidance: use var when the RHS obviously names the type (new ArrayList<String>(), factory methods like List.of(...), static types that are all over your codebase).
Lambdas + inference
Function<String, Integer> len = s -> s.length(); — the parameter type is inferred from the target type (Function<String, Integer>). Combined with var, you get var fn = (Function<String, Integer>) s -> s.length(); — but usually just declare the functional type.
Build a var style checker
Write checkVar(declaration) that takes { rhs: string, varName: string } and returns 'good' or 'bad' with a reason. Rules: good if RHS contains new Type(...) or Type.of(...); bad if RHS is a bare method call like compute() or get() (hidden type). Run on 6 examples.
Diamond still works with var
var map = new HashMap<String, Integer>(); — var infers HashMap<String, Integer>, not the interface. If you wanted Map<String, Integer>, you still write it out: Map<String, Integer> map = new HashMap<>();. Choose explicit for API boundaries, var for short-lived locals.
Quiz: var and null
var x = null; — legal? No. The compiler can't infer a type from null alone. Write String x = null; or var x = (String) null;.