Java 10 introduced the var keyword for local variable type inference. Released in March 2018, Java 10 allowed developers to write var instead of repeating a local variable’s declared type when the compiler can infer that type from an initializer.
For example, var message = "Hello"; is compiled as a local variable of type String, while var numbers = new ArrayList<Integer>(); is inferred as an ArrayList<Integer>. The variable remains statically typed: var does not make Java dynamically typed, and its type cannot change later. An initializer is required because there would otherwise be no type to infer.
The feature applies to local variables, including variables in traditional for loops and enhanced for loops, and to resource variables in try-with-resources. It does not generally apply to fields, method parameters, or method return types. Java still uses the inferred compile-time type for overload resolution and type checking.
The idea is related to local type inference in other languages, but Java deliberately limits var’s scope. A common mix-up is Java 11, which was the next long-term-support release; the feature itself arrived in Java 10.