CoreJava Java10

Java 10 Local Variable Type Inference (var keyword) – Complete Guide

Java 10 Local Variable Type Inference (var keyword) – Complete Guide

Java 10 introduced one of the most talked-about developer productivity features in years: local variable type inference using the var keyword. Before Java 10, you had to explicitly declare the type of every local variable, even when the compiler could obviously figure it out from context. The var keyword lets the compiler infer the type automatically, reducing boilerplate without sacrificing type safety.

In this tutorial, you will learn what var is, how it works under the hood, where you can and cannot use it, and practical examples that show how it makes your code cleaner.

What is Local Variable Type Inference?

Type inference means the Java compiler determines the type of a variable from the expression used to initialize it. This feature is described in JEP 286 and is available starting with Java 10.

The key point: var is not a keyword that removes type safety. Java remains a statically typed language. var simply tells the compiler "you already know the type — you figure it out." At runtime, the variable has a fixed concrete type, just like any other local variable.


// Before Java 10 (explicit type)
String message = "Hello Java 10";
List<String> names = new ArrayList<>();

// With Java 10 var (type inferred by compiler)
var message = "Hello Java 10";      // inferred as String
var names   = new ArrayList<String>();  // inferred as ArrayList<String>

Rules for Using var

var can only be used in these places:

  • Local variable declarations with an initializer
  • For-loop index variables
  • Enhanced for-loop variables
  • Try-with-resources variables

var cannot be used for:

  • Method parameters
  • Return types
  • Fields (class-level variables)
  • Variables without an initializer (var x; is illegal)
  • Variables initialized to null

Complete Example: Java 10 var with Primitives and Objects


package com.java9r;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Demonstrates Java 10 local variable type inference (var keyword).
 * Compile and run with: javac --release 10 Java10VarDemo.java
 */
public class Java10VarDemo {

    public static void main(String[] args) {

        // 1. Primitives – var infers int, double, boolean
        var count   = 10;           // int
        var price   = 99.99;        // double
        var active  = true;         // boolean

        System.out.println("count  : " + count);
        System.out.println("price  : " + price);
        System.out.println("active : " + active);

        // 2. String
        var greeting = "Welcome to Java 10 type inference!";
        System.out.println(greeting);

        // 3. ArrayList – no need to repeat the type on the right side
        var products = new ArrayList<String>();
        products.add("Laptop");
        products.add("Keyboard");
        products.add("Mouse");

        // 4. Enhanced for-loop variable
        System.out.println("\nProduct List:");
        for (var product : products) {
            System.out.println("  - " + product);
        }

        // 5. HashMap
        var inventory = new HashMap<String, Integer>();
        inventory.put("Laptop",   50);
        inventory.put("Keyboard", 200);
        inventory.put("Mouse",    350);

        // 6. Traditional for-loop with var index
        var keys = new ArrayList<>(inventory.keySet());
        for (var i = 0; i < keys.size(); i++) {
            var item = keys.get(i);
            System.out.println(item + " in stock: " + inventory.get(item));
        }
    }
}

Expected Output


count  : 10
price  : 99.99
active : true
Welcome to Java 10 type inference!

Product List:
  - Laptop
  - Keyboard
  - Mouse
Laptop in stock: 50
Keyboard in stock: 200
Mouse in stock: 350

How the Compiler Sees var

Once you compile the code, var is completely gone. The bytecode is identical to code written with explicit types. You can verify this by decompiling the class file — you will see String, ArrayList, HashMap, not var. This means there is zero performance difference between using var and writing the explicit type.

When to Use var and When to Avoid It

Good uses of var:

  • When the type is obvious from the right-hand side (e.g., var list = new ArrayList<String>())
  • Complex generic types that are verbose: var map = new HashMap<String, List<Integer>>()
  • For-loop variables where the type adds noise
  • Try-with-resources where the type is already named in the constructor

Avoid var when:

  • The initializer is a method call and the return type is not obvious: var result = processData(); — what type is result?
  • Working with numeric literals: var x = 1_000_000; — is it int or long?
  • The code is reviewed by people unfamiliar with the codebase

var in try-with-resources (Java 10)


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class VarTryWithResources {
    public static void main(String[] args) throws IOException {
        // var works perfectly in try-with-resources
        try (var reader = new BufferedReader(new FileReader("data.txt"))) {
            var line = reader.readLine();
            while (line != null) {
                System.out.println(line);
                line = reader.readLine();
            }
        }
    }
}

Prerequisites

  • Java 10 or later installed
  • Any IDE (IntelliJ IDEA 2018.1+, Eclipse Photon+, VS Code with Java extension)
  • Basic understanding of Java variable declarations

Summary

Java 10's var keyword makes local variable declarations shorter and easier to read without removing any type safety. The compiler infers the type at compile time, so the bytecode is identical to explicitly typed code. Use var when the type is clear from context, and avoid it when it would make the code harder to understand at a glance. In the next posts in this series, we will see var used with Map, List, Set, and arrays in real-world patterns.

Topics: CoreJava Java10
← Newer Post