Demystifying ‘var’ In Java

Introduction

From Java 10 onwards the compiler autodetects the type of the variable and this process is known as Type inference. Since the compiler can detect the type then the actual type can be replaced by the ‘var’ keyword. But ‘var’ should be used only to declare the local variable, something like

Circle circle = new Circle(); 

Can be replaced by,

var circle = new Circle(); 

The article explains the internals of the ‘var’ keyword in Java, also explains some of the important concepts like whether the introduction of the ‘var’ keyword makes Java a dynamically typed language. Let’s explore.

Can ‘var’ make Java 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’ also the Java compiler infers the type at compile-time using the type of information during variable initialization as mentioned in the above code. Let’s understand by an example of Java and Python, Python is Dynamically Typed. 

Java

var id = 20;
id = "Test";

Type mismatch: cannot convert from String to int

The compiler interprets ‘id’ as Integer, on re-assigning to String generates a compilation error.

Python

id = 20
id = "Test"
print(id) # Test

Python is successfully able to interpret the type at run-time which confirms that Python is Dynamically Typed and in Java compilation error is thrown which makes Java Statically Typed. 

Can ‘var’ be declared as null?

var variable cannot be initialized to null, because with null it is not clear to Java, what type can a variable be during the execution of a program. The reason is the same, Java is statically typed, and trying to declare var as null generates a compile-time error.

var id = null;

Cannot infer type for local variable initialized to 'null'

‘var’ cannot be used as a method parameter and in method return types

For the same reason as discussed above, we cannot use local variable type inference with method arguments and method return types, hence ‘var’ cannot be passed as method parameters and method return types.

‘var’ in inheritance

In the Inheritance scenario, imagine a ‘Shape’ Interface and two subclasses ‘Rectangle’ and ‘Square’ which implement the ‘Shape’ interface.

var shape = new Circle();
System.out.println(shape.getClass());

The above code confirms, that var is of type Circle. The compilation error will be thrown as discussed earlier if we try to re-assign ‘shape’ variable.

var shape = new Circle();
shape = new Rectangle();

What if the type is not provided with ‘var’ with a collection?

var list = new ArrayList<>();

When the type is not provided, it’s inferred as ArrayList<Object>

Using ‘var’ in Lambda Expressions

From Java 11, var can be used as Lambda expression parameters. In an earlier version of Java (10) ‘var’ was not allowed as a Lambda expression parameter. Let’s understand by an example, consider an interface Shape, which has one method ‘radius’ for calculating the radius.

public interface Shape {
    public Integer radius(Integer length, Integer width);
}

The Rectangle class is the core class of Shape, which is having a method for calculating radius

public class Rectangle {
    public void calculate() {
        Shape shape = (Integer len, Integer breadth) - > len * breadth;
        Integer result = shape.radius(15, 4);
        System.out.println(result);
    }
    public static void main(String[] args) {
        Rectangle r = new Rectangle();
        r.calculate();
    }
}

Although inside Lambda expression parameter is not required, it’s inferred automatically, replace Integer by ‘var’

public void calculate() {
    Shape shape =
        var len,
            var breadth) - > len * breadth;
Integer result = shape.radius(15, 4);
System.out.println(result);
}

The advantage of using ‘var’ inside Lambda expression is, type annotations can be applied to local variables

public void calculate() {
    Shape shape = (@NonNull
        var len, @NonNull
        var breadth) - > len * breadth;
    Integer result = shape.radius(15, 4);
    System.out.println(result);
}

Summary

The enhancements and new features in every Java version are building blocks of another feature, the ‘var’ keyword is a good introduction and it’s helpful especially when we have long class names.


Similar Articles