Local Variable Type Inference

Naveen AnamaneniUpdated · 4 min read

When the type of a variable is already obvious from the right-hand side, writing it again feels like saying "Rajdhani Express train" when everyone knows the Rajdhani is a train. Since Java 10, you can write var instead of the type for local variables, and the compiler works out the type for you. The variable is still strictly typed; you just don't have to repeat yourself.

Same Type, Less Typing

The type is decided at compile time, from the value you assign, and it never changes after that:

Explicit typeWith varType the compiler picks
int seats = 72;var seats = 72;int
double fare = 449.5;var fare = 449.5;double
String city = "Pune";var city = "Pune";String
ArrayList<String> stops = new ArrayList<String>();var stops = new ArrayList<String>();ArrayList<String>
Stops.java▶ Try it
import java.util.ArrayList;
 
public class Stops {
    public static void main(String[] args) {
        var train = "Shatabdi";
        var seats = 72;
        var stops = new ArrayList<String>();
        stops.add("Chennai");
        stops.add("Bengaluru");
 
        System.out.println(train + " has " + seats + " seats in coach C1");
        System.out.println("Stops: " + stops);
    }
}
Output
Shatabdi has 72 seats in coach C1
Stops: [Chennai, Bengaluru]

How it works

  1. Lines 5 to 7 declare three local variables with var. The compiler sees "Shatabdi", 72 and new ArrayList<String>() and gives them the types String, int and ArrayList<String>.
  2. These types are fixed. Writing seats = "full"; later is a compile error, exactly as if you'd written int.
  3. In the compiled bytecode, there's no trace of var: it's the same as writing the types out.

Try it yourself: add seats = "full"; after line 6 and compile. Which type does the error message mention?

Where var Works, and Where It Doesn't

AllowedNot allowed
Local variables with a value: var total = 0;Fields: var count; in a class
for loops: for (var i = 0; i < 5; i++)Method parameters and return types
Enhanced for: for (var stop : stops)Without a value: var y;
try-with-resources (covered later in the course)With null: var x = null;

The last two fail because the compiler has nothing to work out the type from:

Compiler output
VarNoInit.java:3: error: cannot infer type for local variable y
        var y;
            ^
  (cannot use 'var' on variable without initializer)
VarNull.java:3: error: cannot infer type for local variable x
        var x = null;
            ^
  (variable initializer is 'null')

The Diamond Trap

The diamond <> asks the compiler to fill in the type from the variable's declared type. With var, there is no declared type to copy, so this compiles but loses the type:

Diamond.java
var stops = new ArrayList<>();   // ArrayList<Object>, not ArrayList<String>
stops.add("Chennai");
stops.add(42);                   // also accepted: probably a bug

With var, always write the type inside the angle brackets: new ArrayList<String>().

Common Mistakes

Thinking var can hold different types over time. It can't. var x = 10; makes x an int for its whole life.

Using var with a decimal literal and expecting float. var price = 99.5; is a double. Write 99.5f if you really want a float.

Hiding important types. var amount = getAmount(); could be int, double or BigDecimal. For money, the type matters; write it out.

Practice

  1. Easy: Rewrite these with var: int count = 0;, String name = "Srihitha";, double rate = 0.18;, long pnr = 4512345678L;. Which type does each get?
  2. Harder: In Stops, use for (var stop : stops) to print each stop on its own line.

Quick check: var

4 questions
1What type does var seats = 72; give seats?
2Which line compiles?
3What is the type of stops in var stops = new ArrayList<>();?
4When was var added to Java?

Key Takeaways

Was this tutorial helpful?

Lesson 41 of 482