BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ Language basics

Java language

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>();.

๐Ÿ”Ž Unravel this example

At a glance

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.

What happens, in order
  1. 1var works only for local variables with an initialiser, for-loop variables and lambda parameters, not for fields, method parameters or return types
  2. 2The type is fixed at compile timevar x = 1; x = "a"; is an error because x is an int.
  3. 3The diamond and var together: var map = new HashMap<String, List<Integer>>(); says the long type once instead of twice
Remember
Watch out
Using var with a diamond and no type arguments, getting ObjectWriting var where the type is not obvious to the readerExpecting var to make Java dynamically typed
Example (highlighted lines explain it)
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();  }}
  1. line 3 uses var, the core of var and type inference
  2. 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 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 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:

Part of a learning path

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.