Unravel โบ Java concepts โบ Language basics
var and type inference
var lets the compiler work out the type of a local variable from the right-hand side: var users = new ArrayList<User>();.
At a glance
Writing "the usual" at the coffee shop: the barista knows exactly what you mean, but you have not named the drink every time.
- 1var works only for local variables with an initialiser, for-loop variables and lambda parameters, not for fields, method parameters or return types
- 2The type is fixed at compile timevar x = 1; x = "a"; is an error because x is an int.
- 3The diamond and var together: var map = new HashMap<String, List<Integer>>(); says the long type once instead of twice
- Use var when the type is obvious from the right side (new, a clear method name) and avoid it when it hides information (var x = process();)
- var list = new ArrayList<>(); infers ArrayList<Object>, usually not what you meant
- There is no var type in the bytecode
public class Totals { public int total(java.util.List<String> lines) { var counts = new java.util.HashMap<String, Integer>(); for (var line : lines) counts.merge(line, 1, Integer::sum); return counts.size(); }}- line 3 uses var, the core of var and type inference
- line 4 uses var, the core of var and type inference
Read the full explanation (about 1 min)
var lets the compiler work out the type of a local variable from the right-hand side: var users = new ArrayList<User>();. It is still strongly typed, just shorter to write.
A mental model
Writing "the usual" at the coffee shop: the barista knows exactly what you mean, but you have not named the drink every time.
How it works
var works only for local variables with an initialiser, for-loop variables and lambda parameters, not for fields, method parameters or return types.
The type is fixed at compile time. var x = 1; x = "a"; is an error because x is an int.
The diamond and var together: var map = new HashMap<String, List<Integer>>(); says the long type once instead of twice.
Going deeper
Use var when the type is obvious from the right side (new, a clear method name) and avoid it when it hides information (var x = process();). Good variable names matter more than before.
var list = new ArrayList<>(); infers ArrayList<Object>, usually not what you meant.
It also captures non-denotable types such as anonymous classes, which allows access to their extra members.
Under the hood
There is no var type in the bytecode. The compiler substitutes the inferred type during attribution, so the class file is identical to the one with the type written out.
Common mistakes
- Using
varwith a diamond and no type arguments, gettingObject. - Writing
varwhere the type is not obvious to the reader. - Expecting
varto make Java dynamically typed.
How Unravel recognises it
When you paste code, Unravel looks for these signs of var and type inference. Spotting them yourself is a good habit when you read unfamiliar code:
- Types:
var
Part of a learning path
- Modern Java syntax ยท previous: Loops, labels and do-while ยท next: Text blocks
Related concepts
Frequently asked questions
What is var and type inference?
var lets the compiler work out the type of a local variable from the right-hand side: var users = new ArrayList<User>();. It is still strongly typed, just shorter to write.
What are the most common mistakes with var and type inference?
Using var with a diamond and no type arguments, getting Object. Writing var where the type is not obvious to the reader. Expecting var to make Java dynamically typed.
How can I see var and type inference in real code?
Paste your own Java into Unravel and it will point out where var and type inference appears, explain how it works at the detail level you choose, and draw the flow of the code around it.