All topics
library
beginner

Local Variable Type Inference (var)

Use var for local variables where the type is obvious, and know when NOT to use it.

var lets the compiler work out a local variable's type from its initialiser.

var = 'you know what I mean.' When someone hands you a coffee (new Coffee()), you don't need to announce 'I am now holding a Coffee' — it's obvious.

Key Concepts

1
    var list = new ArrayList<String>();     // ArrayList<String>
    var count = 0;                          // int
    var name = "Asha";                      // String
2
It is still static typing. The type is fixed at compile time and the bytecode is identical to writing it out. Nothing is dynamic:
3
    var n = 1;
    n = "text";              // will not compile
4
Where it works.
    local variables with an initialiser
    for (var item : list)
    for (var i = 0; i < 10; i++)
    try (var conn = getConnection())
    (var a, var b) -> a + b          // Java 11, to allow annotations
5
Where it does not.
    method parameters
    return types
    fields
    var x;                   no initialiser, nothing to infer
    var x = null;            null has no useful type
    var a = {1, 2, 3};       an array initialiser needs a target type
6
Use it when the right-hand side already says the type.
    var orders = new HashMap<String, List<Order>>();
7
That removes a genuinely noisy repetition. The reader loses nothing.
8
Avoid it when the type disappears.
    var result = service.process();     // what is result?
9
The reader now has to open process() to find out. Write the type instead.
process()
10
The diamond case is worth a thought:
    var list = new ArrayList<>();       // ArrayList<Object> -- probably not intended
11
With var on the left there is nothing to infer the element type from, so it falls back to Object.
varObject
12
And watch the inferred type of a literal:
    var x = 1;               // int
    var y = 1L;              // long
    byte b = 1;              // byte
    var c = (byte) 1;        // byte, only because of the cast
13
The rule of thumb. var where the initialiser is a constructor call or an obvious literal; the explicit type where it is a method call whose return type is not evident from the name.
var
14
What the interviewer is probing.1. "Does var make Java dynamically typed?" Probing: the commonest misconception. Stalls: "It is like JavaScript." Moves up: no — the type is inferred at compile time and fixed, so reassigning a different type does not compile and the bytecode is identical.
15
2. "Where can var not be used?" Probing: the boundaries. Stalls: "Anywhere a type goes." Moves up: parameters, return types, fields, without an initialiser, with null, or with an array initialiser — anywhere there is nothing to infer from.
16
3. "var list = new ArrayList<>(); what type is list?" Probing: the diamond interaction. Stalls: "Whatever you add to it." Moves up: ArrayList<Object> — there is nothing on the left to infer the element type from, which is almost never what was meant.
17
4. "When does var hurt readability?" Probing: judgement rather than a rule. Stalls: "Never, it is shorter." Moves up: when the right-hand side is a method call whose return type is not evident from the name — var result = service.process() tells the reader nothing.