The var Keyword
Reading Time: 6 Minutes
Difficulty: Beginner
Topic Summaryโ
Introduced in Java 10, the var keyword allows the compiler to automatically infer (figure out) the type of a local variable from its assigned value. Instead of writing ArrayList<String> list = new ArrayList<>(), you write var list = new ArrayList<String>(). The code becomes shorter, but the type safety remains exactly the same โ var is NOT a dynamic type like JavaScript's var.
What You'll Learnโ
- What
varis and how it works - The strict rules for using
var - Where
varcan and cannot be used - When to use
varand when to avoid it
Prerequisitesโ
- Basic Java variable declarations
- Understanding of data types in Java
Explanationโ
What is var?โ
var is a reserved type name (not a keyword, technically) that tells the Java compiler: "figure out the type for me based on what I'm assigning."
// Without var
ArrayList<String> names = new ArrayList<String>();
Map<String, List<Integer>> map = new HashMap<String, List<Integer>>();
// With var โ much shorter
var names = new ArrayList<String>();
var map = new HashMap<String, List<Integer>>();
The type is inferred at compile time โ this is NOT dynamic typing. The variable names is still ArrayList<String> after the compiler processes it. At runtime, there is zero difference.
How the Compiler Infers the Typeโ
The compiler looks at the right-hand side of the assignment:
var x = 42; // inferred as int
var pi = 3.14; // inferred as double
var name = "Alice"; // inferred as String
var list = new ArrayList<String>(); // inferred as ArrayList<String>
The type is locked at the point of declaration โ you can't reassign a var variable to a different type:
var count = 10;
count = 20; // โ
OK โ still int
count = "hello"; // โ Compile error โ can't assign String to int
Rules for Using varโ
1. Only for local variables โ inside methods, constructors, or initialization blocks:
var x = 5; // โ
inside method
2. Must be initialized at declaration โ the compiler needs the right-hand side to infer type:
var x; // โ Cannot infer type โ no initializer
var x = null; // โ Cannot infer type from null alone
3. Cannot be null without a cast:
var x = (String) null; // โ
inferred as String (rare use case)
4. Cannot be used for method parameters:
void process(var data) { } // โ NOT allowed
5. Cannot be used for fields (class-level variables):
class MyClass {
var count = 0; // โ NOT allowed for fields
}
6. Cannot be used for return types:
var getCount() { return 5; } // โ NOT allowed
7. Cannot be used in lambda parameter types (Java 11 allows it in certain cases):
Consumer<String> c = (var s) -> System.out.println(s); // โ
Java 11+
Where var IS Allowedโ
| Context | Example |
|---|---|
| Local variable in method | var list = new ArrayList<>(); |
| For-each loop variable | for (var item : list) |
| Traditional for loop variable | for (var i = 0; i < 10; i++) |
| Try-with-resources | try (var conn = getConnection()) |
var with Genericsโ
var works great with complex generic types:
// Old โ verbose
Map<String, List<Integer>> studentScores = new HashMap<String, List<Integer>>();
// With var โ cleaner right side
var studentScores = new HashMap<String, List<Integer>>();
Be careful: if you use the diamond operator <> with var, the compiler may infer Object instead of the correct generic type:
var list = new ArrayList<>(); // inferred as ArrayList<Object>! Not ideal
var list = new ArrayList<String>(); // โ
inferred as ArrayList<String>
When to Use varโ
โ Use var when:
- The type is obvious from the right-hand side:
var name = "Alice" - The type is very long and repetitive:
var map = new HashMap<String, List<String>>() - In for-each loops:
for (var student : students) - When using Builder pattern with long chains
โ Avoid var when:
- The type isn't obvious:
var result = getValue()โ what doesgetValue()return? - It reduces readability:
var x = process(y, z)โ what type is x? - The code is part of a public API (though var can't be used in public method signatures anyway)
- For beginners learning type systems โ explicit types are educational
Real-World Analogyโ
var is like saying "you know what I mean" to the compiler. Instead of saying "Give me a red, 2-door, manual transmission Honda Civic" every time, you point to one and say "give me one of those." The compiler knows exactly what you mean by looking at what you're pointing at โ and it locks in that understanding permanently.
Code Exampleโ
Example 1: Basic var Usageโ
import java.util.*;
public class VarDemo {
public static void main(String[] args) {
// Basic types
var age = 25; // int
var salary = 75000.50; // double
var name = "Alice"; // String
var isActive = true; // boolean
System.out.println(name + " | Age: " + age + " | Salary: " + salary);
// Collections
var list = new ArrayList<String>();
list.add("Java");
list.add("Python");
list.add("Go");
// For-each with var
for (var language : list) {
System.out.println("Language: " + language);
}
// Map with var
var scores = new HashMap<String, Integer>();
scores.put("Alice", 95);
scores.put("Bob", 82);
scores.put("Charlie", 78);
for (var entry : scores.entrySet()) {
System.out.println(entry.getKey() + " โ " + entry.getValue());
}
}
}
Outputโ
Alice | Age: 25 | Salary: 75000.5
Language: Java
Language: Python
Language: Go
Alice โ 95
Bob โ 82
Charlie โ 78
Example 2: var with Complex Typesโ
import java.util.*;
import java.util.stream.*;
public class VarWithStreams {
public static void main(String[] args) {
var numbers = List.of(5, 3, 8, 1, 9, 2, 7, 4, 6);
// Without var:
// List<Integer> evenNumbers = numbers.stream()
// .filter(n -> n % 2 == 0)
// .collect(Collectors.toList());
// With var:
var evenNumbers = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println("Even numbers: " + evenNumbers);
// var in traditional for loop
for (var i = 0; i < 5; i++) {
System.out.print(i + " ");
}
System.out.println();
// var with try-with-resources
try (var scanner = new Scanner(System.in)) {
// scanner is inferred as Scanner
System.out.println("Scanner ready");
}
}
}
Outputโ
Even numbers: [8, 2, 4, 6]
0 1 2 3 4
Scanner ready
Example 3: What NOT to Doโ
public class VarMistakes {
// var count = 0; // โ NOT allowed as class field
public static void main(String[] args) {
// โ
Good โ type is obvious
var message = "Hello World";
// โ ๏ธ Questionable โ what type is result?
var result = compute(); // hard to tell without checking compute()
// โ This gives ArrayList<Object> โ not what you probably want
var list = new ArrayList<>(); // use ArrayList<String>() instead
// โ
Better
var typedList = new ArrayList<String>();
typedList.add("Java");
System.out.println(message);
System.out.println(typedList);
}
static String compute() {
return "done";
}
}
Outputโ
Hello World
[Java]
Common Mistakesโ
- โ Mistake: Using
varwithout initialization:var x;โ โ Fix: Always provide a value:var x = 5; - โ Mistake: Using
var x = null;expecting type inference โ โ Fix: Compiler can't infer type from null alone โ use explicit type or cast:var x = (String) null - โ Mistake: Using
varin method parameters or return types โ โ Fix:varis only for local variables โ not parameters, fields, or return types - โ Mistake: Using
var list = new ArrayList<>()without specifying generic type โ โ Fix: Usevar list = new ArrayList<String>()so the inferred type isArrayList<String>notArrayList<Object> - โ Mistake: Overusing
varand making code unreadable โ โ Fix: If the type isn't obvious from the right-hand side, use an explicit type
Best Practicesโ
- Use
varwhen the type is obvious and the right-hand side clearly shows what it is - Avoid
varwhen the method/constructor name doesn't make the type obvious - Use
varfreely in for-each loops โ it almost always improves readability - Don't use
varfor primitive types likeint,doublein simple cases โ explicit types are fine and clear - Code reviews: if a teammate can't tell the type of a
varvariable in 2 seconds, use an explicit type
Interview Questionsโ
Q: What is var in Java 10?
A: var is a reserved type name in Java 10 that enables local variable type inference. The compiler infers the variable's type from its initializer expression. It is not dynamic typing โ the type is fixed at compile time.
Q: Where can var NOT be used?
A: var cannot be used for: class fields, method parameters, method return types, or variables without an initializer. It's only for local variables inside methods, constructors, and initializer blocks.
Q: What is the difference between Java's var and JavaScript's var?
A: They are completely different. Java's var uses compile-time type inference โ the type is determined by the compiler and is fixed. Once a var variable is declared as int, it stays int. JavaScript's var is truly dynamic โ the same variable can hold different types at runtime.
Q: Can you use var with generics?
A: Yes, but be careful. var list = new ArrayList<String>() correctly infers ArrayList<String>. But var list = new ArrayList<>() infers ArrayList<Object> because the diamond operator alone doesn't specify the type.
Quick Revisionโ
โ var = local variable type inference โ introduced in Java 10
โ Compiler figures out type from right-hand side at compile time
โ Type is locked โ var is NOT dynamic typing
โ Rules: only local variables, must be initialized, cannot be null alone
โ Cannot use on fields, parameters, or return types
โ Use when type is obvious; avoid when type is unclear from context
Related Topicsโ
- Java Generics
- Type System in Java
- Records (Java 16)
- Java Streams with var
Next Lessonโ
Lesson 9 โ Records