Java tutorials > Modern Java Features > Java 8 and Later > What is local-variable type inference (`var` in Java 10)?

What is local-variable type inference (`var` in Java 10)?

Java 10 introduced local-variable type inference, allowing you to declare variables using the var keyword when the type can be inferred from the initializer. This simplifies code by reducing verbosity without sacrificing type safety.

Basic Usage of `var`

In this example, the var keyword is used to declare variables without explicitly specifying their types. The compiler infers the types based on the values assigned to them. message becomes a String, number becomes an int, and list becomes an ArrayList<String>.

Note that var can only be used for local variables with initializers. You cannot use it for fields, method parameters, or when the initializer is null or ambiguous.

import java.util.ArrayList;

public class VarExample {
    public static void main(String[] args) {
        var message = "Hello, var!"; // String
        var number = 10;           // int
        var list = new ArrayList<String>(); // ArrayList<String>

        System.out.println(message);
        System.out.println(number);
        System.out.println(list.getClass());
    }
}

Concepts Behind the Snippet

The core concept behind var is type inference. The Java compiler analyzes the right-hand side of the assignment to determine the appropriate type for the variable. This doesn't introduce dynamic typing. The type is inferred at compile time, and the variable remains statically typed.

It's important to understand that var is not equivalent to Object or dynamic typing. The type is determined at compile time, and the variable retains that type throughout its scope.

Real-Life Use Case Section

Consider working with streams, especially when the type of the stream operation's result can be lengthy. var makes the code more concise and readable. This is especially helpful in complex chained operations. In these situations it is best practice to use descriptive names to make the code easier to read.

import java.util.stream.IntStream;

public class RealWorldVar {
    public static void main(String[] args) {
        var sum = IntStream.rangeClosed(1, 100)
                         .sum(); // int

        var result = IntStream.rangeClosed(1,5)
                .boxed()
                .map(String::valueOf)
                .reduce("", (a, b) -> a + b);

        System.out.println("Sum: " + sum);
        System.out.println("Result: " + result);
    }
}

Best Practices

  • Use meaningful variable names: Even with var, descriptive names are crucial for code readability.
  • Avoid overuse: Don't use var when the type is not immediately clear from the initializer. Explicitly declare the type in such cases.
  • Keep initializers simple: Complex initializers can make it difficult to understand the inferred type.
  • Prefer clarity over brevity: If using var makes the code harder to understand, use an explicit type declaration instead.

Interview Tip

When discussing var in an interview, emphasize that it's a compile-time feature for local variable type inference, not dynamic typing. Explain that it improves code readability by reducing verbosity, especially when the type is obvious from the initializer. Be prepared to discuss the best practices and potential drawbacks of using var.

When to Use Them

Use var when:

  • The type is obvious from the initializer.
  • It makes the code more concise and readable.
  • You're working with long or complex type names.

Avoid var when:

  • The type is not immediately clear.
  • It reduces code readability.
  • The initializer is null or ambiguous.

Memory Footprint

The use of var does not affect the memory footprint of your application. The type is inferred at compile time, and the compiled code is identical to what it would be if you had explicitly declared the type. There is no runtime overhead associated with using var.

Alternatives

Before Java 10, the alternative was to explicitly declare the type of the variable. While more verbose, this approach provides explicit type information and can improve code clarity in some cases. Explicit type declaration is always a valid alternative, especially when the type is not immediately apparent.

Pros

  • Reduced verbosity, leading to more concise code.
  • Improved readability when the type is obvious.
  • Easier to refactor code, as you don't need to update variable declarations if the type of the initializer changes (within limits).

Cons

  • Can reduce code readability if the type is not immediately clear.
  • Potential for misuse if not used judiciously.
  • May require more attention to the initializer to understand the variable's type.

FAQ

  • Can I use `var` for instance variables or class fields?

    No, `var` can only be used for local variables within methods, constructors, initializers, and enhanced for-loops. It cannot be used for instance variables, class fields, method parameters, or return types.
  • Does `var` introduce dynamic typing to Java?

    No, `var` does not introduce dynamic typing. The type of the variable is still determined at compile time based on the initializer. The variable remains statically typed throughout its scope.
  • What happens if the initializer is null when using `var`?

    You cannot use `var` with a null initializer without providing additional type information. The compiler needs to infer the type from the initializer, and a null value does not provide enough information. For example, `var x = (String) null;` is valid.
  • Is `var` a reserved keyword in Java?

    No, `var` is not a reserved keyword but rather a reserved type name. This means you can still use `var` as a variable name (though it's highly discouraged to avoid confusion), but you cannot use it as a class name or package name.