Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In Java 10, use var in a local variable declaration when its initializer makes the type clear: var count = 1; infers int. The compiler still assigns a fixed, static type; var does not make Java dynamically typed. The practical choice is whether omitting the type removes clutter or hides information you need to understand the code.

What Java 10’s var does

Java SE 10 introduced local variable type inference through Oracle’s Java SE 10 announcement and JEP 286. Instead of writing a type on the left side of a local declaration, you can write var and let the compiler infer the type from the initializer.

For example, var names = new ArrayList<String>(); gives names the type ArrayList<String>. This is a source-level convenience: the compiler determines a type as it would for an explicit declaration. The variable does not change type later, and the feature does not alter runtime behavior or require class-file changes, according to the OpenJDK JEP 286 FAQ.

var is a reserved type name, not a Java keyword. Its use is limited to contexts where a local variable’s type is inferred; it is not a replacement for types in fields, method parameters, or method return declarations.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to declare local variables with var

Give the variable an initializer on the same declaration. The initializer supplies the information the compiler needs to infer the type.

var count = 1;                        // int
var names = new ArrayList<String>(); // ArrayList<String>
var path = Paths.get(fileName);       // Path

The Java SE 10 Language Specification defines inference from the initializer treated as a standalone expression. In everyday terms, the right-hand side determines the type; later assignments must be compatible with it. For instance, a variable inferred as int cannot subsequently hold a String.

The feature also works for loop variables and try-with-resources declarations:

for (var name : names) {
    System.out.println(name); // name is String
}

try (var input = new FileInputStream(fileName)) {
    // input is FileInputStream
}

Oracle’s Java language guide documents these forms. Java 11 later added var syntax for explicitly naming the inferred type of implicitly typed lambda parameters; that addition was not part of Java 10.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What var cannot be used for

The initializer is mandatory and must provide a type on its own. The Java SE 10 specification lists these compile-time restrictions:

  • No initializer: var value; is illegal.
  • A null initializer: var value = null; is illegal because the inferred type would be the null type.
  • A lambda or method reference by itself: var task = () -> {}; is illegal because it needs a target functional-interface type.
  • An array initializer without an explicit array-creation expression: var values = { 6 }; is illegal because an array initializer needs a target type.
  • Multiple declarators in one statement: var first = 1, second = 2; is illegal.
  • Extra array brackets after the variable name, as in var values[] = new int[4];, are illegal.
  • Using the variable in its own initializer, as in var value = (value = 7);, is illegal.

These are rules of the Java 10 language specification, not just style recommendations. When an expression does not stand alone with a determinable type, supply the needed type explicitly or rewrite the declaration.

Is var dynamically typed?

No. The compiler infers a static type once, at compile time. The variable behaves as if that type had been written explicitly, and ordinary Java type checking still applies. Brian Goetz, author of the JEP 286 FAQ, puts it plainly: “No! Variables are still statically typed, as they have always been.” (OpenJDK FAQ.)

For example, if var names = new ArrayList<String>(); infers ArrayList<String>, the compiler will not let the same variable later refer to an unrelated type. The runtime does not inspect or adjust the variable’s type as values change.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When to use var and when to keep the type

Decide by asking two questions: does the initializer make the inferred type apparent, and does an explicit type communicate a useful abstraction that the initializer does not? The OpenJDK style guide captures the tradeoff: “It can make code more readable by eliminating redundant information, and it can also make code less readable by eliding useful information.” (OpenJDK Local Variable Type Inference Style Guidelines, March 2018.)

Situation Usually clearer Why
The initializer repeats the type, such as new BufferedReader(...). var reader = new BufferedReader(...); The constructor already reveals the concrete type, so writing it twice can be redundant.
The right-hand side is a clear, well-named factory call, such as Paths.get(fileName). var path = Paths.get(fileName); The name and surrounding code can make the role easy to understand.
The initializer is opaque, or an explicit interface communicates the intended abstraction. Write the type explicitly, such as List<String> names = loadNames(); The declared type may tell readers more than the method call or concrete implementation does.
The variable name is vague and the initializer does not clarify its role. Improve the name, and consider retaining the type. var removes a type label, so the remaining expression and name must carry enough context.

Use var where the initializer and surrounding code make the type or purpose easy to follow. Keep an explicit type when it signals an important abstraction, clarifies an otherwise opaque expression, or makes the code easier to review without relying on an IDE to reveal the type. This is a readability choice, not a compiler requirement; Oracle and the OpenJDK style guide both recommend judgment rather than a universal rule.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.