Local Variable Type Inference
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 type | With var | Type 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> |
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);
}
}Shatabdi has 72 seats in coach C1
Stops: [Chennai, Bengaluru]How it works
- Lines 5 to 7 declare three local variables with
var. The compiler sees"Shatabdi",72andnew ArrayList<String>()and gives them the typesString,intandArrayList<String>. - These types are fixed. Writing
seats = "full";later is a compile error, exactly as if you'd writtenint. - 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
| Allowed | Not 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:
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:
var stops = new ArrayList<>(); // ArrayList<Object>, not ArrayList<String>
stops.add("Chennai");
stops.add(42); // also accepted: probably a bugWith 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
- Easy: Rewrite these with
var:int count = 0;,String name = "Srihitha";,double rate = 0.18;,long pnr = 4512345678L;. Which type does each get? - Harder: In
Stops, usefor (var stop : stops)to print each stop on its own line.
Key Takeaways
Was this tutorial helpful?