How to Embrace local variable type inference “var” in Java

int i = 10; This is the standard variable declaration in java, you have got the variable type here int followed by variable name and then an assignment to the value 10. Now with Java 10 onward, you can also do the same thing using var declaration.

var i =10;

This JEP proposes the use of type inference while we declare the variables along with initialization.

From the inception , java has always been a type safe language, the compiler has to know at any time what the type of certain variable is, be it a primitive or be a custom class type. That hasn’t changed in Java, Java is still a type safe language however it is also true that now you can also use var keyword to declare variable in java like var x = 10;

It is a new addition to the language(Java 10) called “local variable type inference”.meaning when you declaring a variables where the type of the variables can be inferred by the compiler, you can drop the type and say var instead. all it does is offer us declare the variables along with initialization in certain conditions.

So instead of declaring the data member like :

int x =10;

we can now declare and initialize the variable as:

var x = 10;                          // infers integer value
var demo = new Demo(); // infers Demo class
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>

the data type of x is inferred by compiler from the right hand side and it is considered to be of type int.

Caution!!

Use var keyword carefully while considering the implicit up-casting.

e.g.

double x = 20;

Can be replaced by:

var x = 40;

but this will consider the data type as int rather than double. So, it is recommended to use literals in such cases,

var x = 40D;

The above statement now considers the data type of 40 as double.

Currently this keyword can be used only in :

  • Locally declared variable with initialization
  • Indexes which are declared in the enhanced for loop
  • local variables that are declared in the traditional for loop

You cannot use this keyword in :

  • formal arguments
  • formal arguments of the constructors
  • Returns type of the methods
  • Arguments in catch block

Of course, there could be a lot of confusion on the developers mind before using this feature, Let us understand how all such concepts work with this new introduction of var keyword.

Compile time safety

Java’s commitment to static type safety, when we declare the variable with var keyword the data type of the variable cannot be changed according to the data passed to it. consider the following snippet:-

public void changeIt(){
var x = 10;
x = "Hello World" // Type mismatch: cannot convert from String to int
}

In the above example, the value of x, which was initially 10 of Integer type is changes to string. If you compile above code,compilation will fail with message Type mismatch: cannot convert from String to int

Working with collections and arrays

Using inferred variable declaration can give flexibility to work with arrays and collections. Consider the following example:

public void arrayDemo(){
var data = Arrays.asList(10,20); // statement 1
int x = data.get(1); // statement 2
}
public void ListDemo(){
List<Employee> empList = List.of(e1,e2);
var empList = List.of(e1,e2); // similar to above
}

In above code, statement-1 declare the List of type integer, though we haven’t declared any data type for the same. The compiler generates the data type based on the values passed to this.

Statement-2 in the above code takes a data from the list, which will be the default as type integer, though we have not declared explicitly the data type for the list.

Working with traditional for loop, and for each loop

We can also use the var keyword in the traditional loop as

public void forLoopDemo(){
for(var i = 0; i < 10; i++){ // equivalent to for(int i = 0; i < 10; i++)
System.out.println(i);
}
}
public void forEachDemo(){
var arr = new String[]{"IND","AUS","SA","ENG","NZ"};
for(var data : arr){
System.out.println(data);
}
}

Working with Java Streams

var data = Stream.of("IND","AUS","SA","ENG","NZ");

Working with try-with-resources

Though, we cannot use var keyword within catch block, It can be used in try-with-resource as follows:

try(var file = new File("demo.txt")){
// code goes here
}

Local Variable Type Inference: Frequently Asked Questions

  1. Does this make Java dynamically typed? Is this like var in JavaScript?

No. Java is still a statically typed language, and the addition of var doesn’t change this. var can be used in a local variable declaration instead of the variable’s type. With var, the Java compiler infers the type of the variable at compile time, using type information obtained from the variable’s initializer.

2. Is a var variable final?

No. Local variables declared with var are non-final by default. However, the final modifier can be added to var declarations:

final var person = new Person();

3. Why can’t you use var with null?

Consider this declaration (which is illegal):

var person = null; // ERROR

The null literal denotes a value of a special null type, this is the sub-type of all reference types in Java. The only value of the null type is null itself, therefore, the only value that could ever be assigned to a variable of the null type is null.