Java var (Type Inference)
Updated 7 min read Aimerscrew
Writing the type of every variable can feel repetitive, especially when the type is long and already obvious from the value. Java var lets the compiler work out the type for you. In this lesson you'll learn what var really does, the places it's allowed and forbidden, and simple rules for when it makes code clearer and when it makes code harder to read.
🌍 Real-life example
At an airport check-in desk, you put your suitcase on the scale and the agent prints the tag: weight, destination, flight number. You don't fill in "this is a suitcase, 18 kg"; the desk works it out from what's on the scale. Once the tag is attached, though, it's permanent. var works the same way: Java reads the value you give it, writes the type on the variable for you, and that type never changes.
What is var in Java?
var declares a local variable (a variable inside a method) without writing its type. The compiler looks at the value on the right side of = and infers the type from it. This feature is called local variable type inference, and it arrived in Java 10.
public class FlightCheckIn {
public static void main(String[] args) {
var passenger = "Noah Kim"; // String
var seatRow = 14; // int
var bagWeight = 18.5; // double
var hasPriority = false; // boolean
System.out.println(passenger + ", row " + seatRow);
System.out.println("Bag: " + bagWeight + " kg, priority: " + hasPriority);
}
}
Noah Kim, row 14
Bag: 18.5 kg, priority: false
Each line behaves exactly as if you'd written the type yourself: passenger is a String, seatRow is an int, and so on. There's no speed cost either; the compiler fills in the types before the program runs.
How does the compiler decide the type?
The compiler uses the same literal rules you learned in Java data types: a whole number is an int, a number with a decimal point is a double, text in double quotes is a String, and so on. For new Something(...), the type is simply Something.
Is Java still statically typed with var?
Yes. This is the most important thing to understand about var. It is not like a variable in Python or JavaScript that can hold anything. The type is decided once, at compile time, and then locked:
var freeSeats = 10;
freeSeats = "ten"; // does not compile
error: incompatible types: String cannot be converted to int
freeSeats is an int forever, just as if you had written int freeSeats = 10;.
Where can you use var?
var works for local variables that are given a value on the same line. That includes variables inside main and other methods, and loop variables, which you'll meet in Java for loop.
import java.util.Scanner;
public class ShopStock {
public static void main(String[] args) {
var input = new Scanner("12 4.99"); // reads from this text instead of the keyboard
var unitsInStock = input.nextInt();
var unitPrice = input.nextDouble();
var stockValue = unitsInStock * unitPrice;
System.out.printf("%d units at %.2f = %.2f%n", unitsInStock, unitPrice, stockValue);
input.close();
}
}
12 units at 4.99 = 59.88
A Scanner can read from a String as well as from the keyboard, which keeps this example's output fixed. The compiler knows nextInt() returns an int and nextDouble() returns a double, so var picks those types.
Where is var not allowed?
The compiler needs a value to look at, and it only allows var inside methods. These all fail:
| Code | Why it fails |
|---|---|
var total; | no value to infer from (cannot use 'var' on variable without initializer) |
var winner = null; | null has no useful type (variable initializer is 'null') |
var x = 1, y = 2; | one variable per var ('var' is not allowed in a compound declaration) |
var scores = {90, 85}; | an array needs its type spelled out (array initializer needs an explicit target-type) |
a class-level variable, such as static var LIMIT = 5; | only local variables can use var ('var' is not allowed here) |
| method parameters and return types | same: 'var' is not allowed here |
📝 Note
Technically, var isn't a keyword but a reserved type name. That's why old code that used var as a variable name still compiles. Don't name your own variables var, though; it's confusing.
The var trap: whole numbers become int
Because var copies the type of the literal, a whole number always becomes an int, even when you meant a decimal or a long. That can quietly break your math:
public class VarTrap {
public static void main(String[] args) {
var pizzaPrice = 10; // int, not double!
var share = pizzaPrice / 4;
System.out.println("Each pays: " + share);
var betterPrice = 10.0; // double
var betterShare = betterPrice / 4;
System.out.println("Each pays: " + betterShare);
var views = 5_000_000_000L; // the L makes it a long
System.out.println("Views: " + views);
}
}
Each pays: 2
Each pays: 2.5
Views: 5000000000
The first share is 2 instead of 2.5 because pizzaPrice is an int, so the division is integer division (remember Java type casting). With an explicit type, double pizzaPrice = 10; would have avoided the problem.
When should you use var?
var is a readability tool. Use it when the type is obvious from the right side, and skip it when a reader would have to guess.
| Good use of var | Better with an explicit type |
|---|---|
var input = new Scanner(System.in);the type is written right there | var x = calculate();what does calculate() return? |
var message = "Order shipped";clearly a String | var rate = 5;did you mean int or double? |
| long type names, such as collection types you'll meet in Java HashMap | values whose exact type matters, like money or very large counts |
A good test: cover the right side of the line with your hand. If the variable name alone tells you what it holds, var is fine. If not, write the type (or improve the name).
💡 Tip
While you're learning, it's perfectly fine to write explicit types everywhere. It helps you practice thinking about types. Use var where it clearly removes repetition.
Real-world example: a weekly step tracker
Here var is used where the type is obvious and an explicit type is kept where it carries meaning:
public class StepTracker {
static final int DAILY_GOAL = 8000;
public static void main(String[] args) {
var owner = "Grace";
var mondaySteps = 9120;
var tuesdaySteps = 6475;
var wednesdaySteps = 10340;
var totalSteps = mondaySteps + tuesdaySteps + wednesdaySteps;
double averageSteps = totalSteps / 3.0; // explicit: we want decimals
var goalTotal = DAILY_GOAL * 3;
System.out.printf("%s walked %,d steps in 3 days.%n", owner, totalSteps);
System.out.printf("Average per day: %,.1f%n", averageSteps);
System.out.printf("Goal for 3 days: %,d%n", goalTotal);
}
}
Grace walked 25,935 steps in 3 days.
Average per day: 8,645.0
Goal for 3 days: 24,000
Common mistakes with var
- Declaring without a value.
var total;doesn't compile. Give it a starting value, or use an explicit type. - Expecting a decimal from a whole number.
var price = 10;is anint. Write10.0or usedouble. - Thinking var makes the type flexible. The type is fixed after the first line, exactly like a normal variable.
- Using var for fields or parameters. It's only for local variables inside methods.
- Using var with vague names.
var data = load();hides both the type and the meaning. Prefer a clear name or an explicit type.
Practice exercise
🏋️ Try it yourself
Write a program for a bike rental shop using var where it fits. Store the customer name ("Omar"), the hours rented (3) and the hourly rate (7.5). Add a class constant for a helmet fee of 2.0. Calculate the total and print it with two decimals. Then think: which variable would be dangerous to declare with var if the rate were a whole number like 7?
Show solution
public class BikeRental {
static final double HELMET_FEE = 2.0;
public static void main(String[] args) {
var customer = "Omar";
var hours = 3;
double hourlyRate = 7.5; // explicit, so a whole-number rate stays a double
var total = hours * hourlyRate + HELMET_FEE;
System.out.printf("%s rented a bike for %d hours.%n", customer, hours);
System.out.printf("Total: %.2f%n", total);
}
}
Omar rented a bike for 3 hours.
Total: 24.50
The rate is the risky one: var hourlyRate = 7; would make it an int, and any later division with it would drop the decimals. Writing double makes your intent clear.
What's next?
Congratulations, you've finished the Variables and Data Types chapter! You can store values, choose types, convert between them, read input and print neat output. Next, start doing math with your variables in Java arithmetic operators.
Key takeaways
- var, added in Java 10, lets the compiler infer a local variable's type from the value assigned to it.
- Java is still statically typed: a var variable's type is fixed at compile time and cannot change.
- var only works for local variables with an initializer, not for fields, parameters or return types.
- var cannot be used with null, without a value, with array initializers or in comma-separated declarations.
- Whole number literals make var infer int, so var price = 10; is not a double.
- Use var when the type is obvious from the right side; write the type when it carries meaning.
Frequently asked questions
What does var do in Java?
var tells the compiler to infer a local variable's type from the value you assign. var count = 5; is compiled exactly like int count = 5;. It was introduced in Java 10.
Does var make Java dynamically typed?
No. The type is decided once at compile time and never changes. Assigning a value of a different type later, such as text to an int variable, is a compile error.
Can I use var for class fields or method parameters?
No. var is only allowed for local variables declared inside methods, including loop variables. Fields, parameters and return types need an explicit type.
Why does var x = null; not compile?
The compiler infers the type from the initializer, and null does not tell it which type you want. Write the type explicitly, for example String winner = null;.
Is var a keyword in Java?
Not exactly. It is a reserved type name, which means it has special meaning in a declaration but old code that used var as a variable name still compiles.