The <code>var</code> Keyword in Java β€” Local Variable Type Inference

var (Java 10+) lets the compiler infer the type of a local variable from its initialiser. It's pure syntactic sugar β€” the resulting bytecode is identical to writing the full type β€” but it significantly tightens ceremony-heavy code.

Where var works

var users    = new ArrayList<User>();        // ArrayList<User>
var map      = Map.of("a", 1, "b", 2);       // Map<String,Integer>
var session  = repo.findById(id);             // inferred from return type

for (var entry : map.entrySet()) { ... }      // Map.Entry<String,Integer>
for (var i = 0; i < 10; i++) { ... }         // int

try (var reader = Files.newBufferedReader(path)) { ... }

Where var doesn't

private var name;                  // ❌ instance fields β€” not allowed
public var handle() { ... }         // ❌ method returns
void f(var x)                       // ❌ parameters
var x;                              // ❌ no initialiser β€” can't infer
var nothing = null;                 // ❌ null has no useful type
var arr = {1, 2, 3};                // ❌ array initialiser without type

When to use it

Use var when the type is obvious from the right-hand side:

var path = Paths.get("/tmp/foo");                       // βœ… clear
var results = service.search(query);                     // ❓ unclear β€” what does search return?
var total = computeTotal();                              // ❓ is it BigDecimal? double? Money?

When in doubt, write the type. Readers shouldn't have to jump to the method signature.

Useful idioms

// Shorter generic declarations
var events = new HashMap<String, List<Event>>();

// Clearer stream collect
var byCity = users.stream()
    .collect(Collectors.groupingBy(User::city));

// Anonymous class with extra methods accessible on the returned type
var runnable = new Runnable() {
    public int counter = 0;
    @Override public void run() { counter++; }
};
runnable.counter;                    // works β€” the type is the anonymous class

Common mistakes

  • Using var where it hides intent β€” var x = process(); tells the reader nothing.
  • Numeric literals β€” var n = 5; gives int, not long; var d = 5; gives int, not double. Use an explicit type or a typed literal (5L, 5.0).
  • Diamond + var β€” var list = new ArrayList<>(); infers ArrayList<Object>. Provide the type argument: new ArrayList<String>().

Related

Pillar: Java keywords. See also Variables, local variables.