Limitations of Local Variable Type Inference in Java

Pradeesh Kumar
3 min readDec 15, 2022

--

Java icons created by Flat Icons — Flaticon

Java 10 introduced a noticeable feature: the Local variable type inference. This allows us to declare local variables without specifying the type using the varkeyword, the compiler automatically infers its type. This reduces the complex boilerplate declarations and makes the code look clean.

Example (Old Way of Declaration):

BufferedInputStream bufferedInStream = new BufferedInputStream(new FileInputStream("data.txt"));
List<String> list = new ArrayList<>();
Map<String, Integer> map = new HashMap<>();

Using var:

var bufferedInStream = new BufferedInputStream(new FileInputStream("data.txt"));
var list = new ArrayList<String>();
var map = new HashMap<String, Integer>();

However, we cannot declare variables everywhere with the varkeyword. There are some restrictions, which are given below.

1. Class level

When we say ‘local’ variable type inference, we can use it strictly in a method's local context. We cannot declare a variable inside a class (static or instance) using the varkeyword. The compiler throws a compilation error if trying to declare it inside a class.

class Example {
int rollNumber;
var name; // Compiler Error! - Cannot resolve symbol 'var'
}

2. Null Assignment

You must assign a non-null value to the variable during the declaration so that the compiler can infer its type. Assigning a null reference to a variable makes the compiler difficulty to infer its type. Hence, the null assignment is not allowed during the declaration.

public static void main(String[] args) {
var name = null; // Compiler Error! - Cannot infer type: variable initializer is 'null'
}

However, you can assign the null after the first initialization.

public static void main(String[] args) {
var name = "hello";
name = null; // Valid now!
}

3. Compound Initialization

Java allows us to initialize multiple variables of the same type in a single statement separated by a comma. int length = 10, breadth = 20, height = 30; However, this is not allowed when you use thevar.

public static void main(String[] args) {
var length = 10, breadth = 20, height = 30; // Compiler Error! 'var' is not allowed in a compound declaration
}

4. Array Initialization

Array initialization is not allowed without specifying its type during the initialization.

public static void main(String[] args) {
var a = { 1, 2, 3 }; // Compiler Error! Array initializer is not allowed here
var[] b = { 1, 2, 3 }; // Compiler Error! Unexpected token.
var[] c = new int[] { 1, 2, 3 }; // Compiler Error! Unexpected token.

var d = new int[] { 1, 2, 3 }; // Valid!
}

5. Lambda Argument

In Java 10,var was limited only to local variables. Java 11 expanded the scope of thevar to Lambda arguments.

Example:

BiConsumer<String, String> example = (var s1, var s2) -> System.out.println(s1 + s2); // Valid!

However, It’s illegal to mix thevar with other types in the Lambda arguments.

BiConsumer<String, String> example = (var s1, String s2) -> System.out.println(s1 + s2); // Compiler error. Cannot mix 'var' and explicitly typed parameters in lambda expression

6. Loop Variable

for loop allows us to initialize multiple variables. Java 10 allows us to use thevar on for loops. However, the compound declaration is not allowed here too.

for (var i = 0; i < 10; i++) { // Valid! Single var declaration is allowed
System.out.println(i);
}


for (var i = 0, j = 10 ; i < 10; i++, j--) { // Compiler error! 'var' is not allowed in a compound declaration
System.out.println(i + j);
}

7. Catch Block

Java allows us to declare multiple catch blocks in order to deal with various exceptions differently. We must specify the exception type in the catch block to handle the particular exception. Hence, using the var in the catch block makes it difficult to know which catch block the exception is to be passed to.

try {
var input = new FileReader("hello.txt");
} catch (var e) { // Compiler Error. Not allowed in catch block
System.out.println("Error occured");
}

Conclusion

Local variable type inference is a noticeable enhancement made in Java 10. It reduces the boilerplate declaration. It can be used only in the method's local context. It’s illegal to use it at the class level, and cannot make a null assignment, compound declaration, array declaration, mixed lambda arguments, and compound declaration in a for-loop and catch block.

--

--

Pradeesh Kumar
Pradeesh Kumar

Written by Pradeesh Kumar

Computer Science | Distributed Computing | Databases | Cloud