1. Introduction
Before discussing local variable type inference, let us review what is type inference in Java.
Following is the way of declaring a list of String in Java.
List<String> movies = new ArrayList<String>();
// In Java 9, the same piece of code can be written as
List<String> movies = new ArrayList<>();
The compiler inferences the type of list be looking at the left hand side of the =.
Let us see another example of type inference.
Predicate<Employee> salary = (Employee e) -> e.getSalary() > 1000000
// This line of code can be rewritten using type inference
Predicate<Employee> salary = e -> e.getSalary() > 1000000
Let us now discuss local variable type inference.
Following is a simple way to declaring a variable of type String
:
String name = "John";
/* This line of code can be rewritten using local variable type inference:*/
var name = "John";
Here, the type of name
is String
. The compiler infers the type of name
by looking at the right hand side of the ‘=’. Let us see another example.
Employee e = new Employee();
// Above code can be rewritten as
var e = new Employee();
2. Is Java still Dynamically Typed Language?
After the introduction of the var
keyword, Java is still a “statically typed language”. The Dynamically Typed Languages performed type checking at run-time, with var
the Java compiler infers the type at compile-time using the type of information provided during variable initialization.
For example, following in not allowed in Java whereas this is allowed in Python which is a dynamically typed language.
var id = 10;
id = "Test";
3. Where can we use var?
3.1 var can be used as local variable with initializer
In the following example, names
is a local variable with value initialized as list.
public static void printNames(){ var names = List.of("John", "James", "Starc", "Shane"); for(var name : names){ System.out.println(name); } }
3.2 Index in a for loop
In the following example, var
is used for each name
in the list of Strings names
.
public static void printNames(){ var names = List.of("John", "James", "Starc", "Shane"); for(var name : names){ System.out.println(name); } }
3.3 try-with-resources
var
can be also be used with try-with-resources. In the following example, var
can be used for a new resource Scanner
.
public void readFile(){ try(var scanner = new Scanner(new File("test.txt"))){ while(scanner.hasNext()){ System.out.println(scanner.nextLine()); } } catch(FileNotFoundException fileNotFoundException) { fileNotFoundException.printStackTrace(); } }
4. Where var can not be used ?
4.1 var can not be used with Class level fields
For example, the following is not possible:
public class Student { var firstName; // not allowed var lastname; // not allowed }
Let us discuss the reason why var
can not be used with class level fields. Suppose you created a class level field with var
and initialized with a String. Later if you changed the initialized value to Integer or some other type, this may lead the breaking of code wherever this field of class is used by other objects. Due to this reason var
is not allowed with Class level fields.
Instance variables (fields) and class variables (static fields) must have explicit types.
4.2 var can not used as method parameter and return type
var
can not be used as method parameter and return type. Following is not allowed:
public class Student { public var setName(var name){ } }
Let us discuss the reason why var
is not allowed as method parameter and return type. Suppose you defined a method with var as method argument and parameter type. Later you changed the return type or method parameter. This may lead to errors wherever this method is used in other objects. Due to this reason var
is not allowed as method parameter and return type.
4.3 Array initializer expressions
When initializing an array using an array initializer expression, you cannot use var
.
var array = {1, 2, 3}; // This is not allowed
4.4 Constructor parameters
Similar to method parameters, constructor parameters also require explicit types.
ClassName(var param) { // This is not allowed // constructor body }
4.5 var is not allowed as catch formal
Following is not allowed:
public void test() { try{ // try body } catch(var e){ // not allowed // catch body } }
5. Few important points to note
var
is a reserved type name, not a keyword, which means that existing code that usesvar
as a variable, method, or package name is not affected. However, code that uses var as a class or interface name is affected and the class or interface needs to be renamed.var var = 10; // Allowed but should be avoided
- local variable declared using var are not final. You can use final with
var
. For example,final var = 10;
- Local variable with
var
always need an initializer. For example, following is not allowed:var x;
Let us discuss why local variable with initializer is not allowed. Suppose, if you write the code something like the following:var x;
var x;
............
............
x = 10;
Here, x is initialized to a string value and later with an integer value. The type of code is changed later from String to int. This may lead to confusion regarding the type of variable and errors. That is why some value is provided when variable is declared which specifies the type of variable. - You should be specify the type where the requirement is very specific. For example:
byte x = 10; // this is byte
var y = 10; // this is int
6. Conclusion
Java 10 introduced local variable type inference with the var
keyword, offering developers a means to write more concise and readable code. By allowing the type of local variables to be inferred from their initialization expressions, Java code becomes less verbose without sacrificing type safety. This feature enhances developer productivity by reducing boilerplate code, especially in scenarios where variable types are evident from the context. While var
facilitates cleaner code, it’s essential for developers to use it judiciously, ensuring that their code remains understandable and maintainable. Overall, Java 10’s local variable type inference with var
represents a significant step forward in modernizing the Java language, making it more expressive and developer-friendly.