Modern Java Features: Local Variable Type Inference

I’m a backend software engineer with over a decade of experience primarily in Java. I started this blog to share what I’ve learned in a simplified, approachable way — and to add value for fellow developers. Though I’m an introvert, I’ve chosen to put myself out there to encourage more women to explore and thrive in tech. I believe that by sharing what we know, we learn twice as much — that’s precisely why I’m here.
Introduced in Java 10 and enhanced in Java 11, local variable type inference allows developers to use the keyword var instead of explicit type declarations for local variables. So, the purpose of this feature is to reduce verbosity.
For instance, rather than writing:
Map<String, List<Integer>> myMap = new HashMap<>();
You can write:
var myMap = new HashMap<String, List<Integer>>(); //infers HashMap
It’s important to note that this doesn't turn Java into a dynamically typed language. The type of myMap is still inferred at compile time based on the right-hand side of the assignment. That is why the use of var is restricted to local variables where the type can be clearly inferred from the initializer. This includes variables declared inside methods, constructors, loops, and other code blocks:
for each-loop:
var names = List.of("Peter", "John", "Mary");
for(var name: names) { // infers String
System.out.println(name);
}
Traditional for-loop:
var names = List.of("Peter", "John", "Mary");
for(var i = 0; i < names.size(); i++) { // infers int
System.out.println(names.get(i));
}
try-with-resources:
try (var input =
new FileInputStream("validation.txt")) {...} // infers FileInputStream
verbose generic types:
var complexMap = new HashMap<String, Map<Integer, List<Double>>>();
In Java 11, Java introduced support for inferred formal parameters in lambda expressions. This allows developers to use var instead of specifying an explicit type for lambda parameters. While using var in this context doesn't make the code shorter—since lambdas typically omit types altogether—it becomes useful when you need to add annotations to parameters.
For example, if you want to annotate a parameter in a lambda expression, you must specify a type. Before Java 11, you had to write:
list.forEach((@Nonnull String item) -> System.out.println(item));
With var, you can now write:
list.forEach((@Nonnull var item) -> System.out.println(item));
This keeps the syntax consistent and avoids having to revert to full-type declarations just to use an annotation.
Note that when using var in lambdas with multiple parameters, all parameters must use var, or none of them. Mixed declarations are not allowed:
(var a, var b) -> a + b // Valid
(var a, b) -> a + b // Invalid
Finally, let’s see some additional examples of when the use of var is not allowed:
varcannot be used for class or instance fields, method parameters, return types (prior to Java 21), or variables without initializers:// Not allowed var uninitialized; // Not allowed in fields class Example { var myField = 42; // Compilation error } // Not allowed in method signature public var doSomething() { ... } // Compilation errorvaris a reserved type name in Java—not a keyword—so existing code that usesvaras a variable, method, or package name still compiles. However, usingvaras a class or interface name will now result in a compilation error.//Not allowed, var is not a valid type name class var {} //Not allowed, var is not a valid type name interface var {}
🧠 Quick Quiz: Test Your Understanding of var in Java
Try answering these questions before scrolling down to the answers!
1️⃣ What will be the inferred type of the following variable?
var items = new ArrayList<String>();
2️⃣ Which of the following usages of var is NOT allowed?
a)
var count = 5;
b)
var processData() { ... }
c)
for (var i = 0; i < 10; i++) { ... }
d)
var stream = Files.lines(path);
3️⃣ True or False:
Using var in a lambda expression allows parameter annotations without reverting to full-type declarations.
4️⃣ What happens if you write this?
var x;
x = 10;
✅ Answers
1. ArrayList<String>
2. b) is not allowed — you can’t use var as a return type in a method signature.
3. ✅ True — You can annotate lambda parameters using var.
4. ❌ Compilation error — var must be initialized on declaration.
Conclusion
Local variable type inference brings a cleaner and more concise syntax. There are no strict rules on when or not to use it, instead, Oracle recommends using it thoughtfully when it will bring clarity rather than not.
Its introduction in Java 10 and later enhancements reflect the language's ongoing evolution toward more expressive and developer-friendly features.




