Java 11 Developer Certification - Local Variable Type Inference (LVTI)

September 30, 2020

What we are covering in this lesson

  1. What is LVTI?

What is Local Variable Type Inference (LVTI)

Local Variable Type Inference or LVTI is also known as var declaration. This is a Java 10 feature introduced to reduce the verbosity of code in some situations. This feature is only available for local variables inside a method body. var is not be confused with data-types, a compiler must be able to infer a datatype while using var. Also, var is not a keyword and hence ‘var’ can be used as an identifier.

package com.maxCode.online.longPackageName.var;

public class AnyRandomClassWithAVeryLongName {
	String name;
	
	public AnyRandomClassWithAVeryLongName() {
		// Default Constructor
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
    public String toString() {
        return "Example for a very long class name = " + name;
    }
}

Now consider we have a java code like the one above. To use this code, we will have to do something like

import com.maxCode.online.longPackageName.var.AnyRandomClassWithAVeryLongName;

public class VarExample {
	public static void main(String[] args) {
		AnyRandomClassWithAVeryLongName anyRandomClassWithAVeryLongName
			= new AnyRandomClassWithAVeryLongName();
		
		anyRandomClassWithAVeryLongName.setName("MaxCode");
		System.out.println(anyRandomClassWithAVeryLongName);
	}
}

As you can already see, class VarExample looks very clumsy due to the fact that that it is creating a new object for the class which has a very long name. Not to mention, we have already imported the package, otherwise the fully qualified name would have been a disaster emoji-smile

Here, instead of the all the clutter, we can use var and make the code more readable.

import com.maxCode.online.longPackageName.var.AnyRandomClassWithAVeryLongName;

public class VarExample {
	public static void main(String[] args) {
		var anyRandomClassWithAVeryLongName = new AnyRandomClassWithAVeryLongName();
		
		anyRandomClassWithAVeryLongName.setName("MaxCode");
		System.out.println(anyRandomClassWithAVeryLongName);
	}
}

Note: var can only be used inside methods for local variables, and compiler must be able to infer the type of variable from the right side of the assignment.

Lets have a look at some of the valid uses of var.

import com.maxCode.online.longPackageName.var.AnyRandomClassWithAVeryLongName;

public class VarExample {
	public static void main(String[] args) {
		var anyRandomClassWithAVeryLongName = new AnyRandomClassWithAVeryLongName();
		
		anyRandomClassWithAVeryLongName.setName("MaxCode");
		System.out.println(anyRandomClassWithAVeryLongName);
		
		//Some more var examples
		var i = 1;	//i will be inferred to be an int
		var varArray = new int[3]; //array assignment is possible
		var varMethod = anyRandomClassWithAVeryLongName.getName(); //inferred to String
		
		Object obj = null;
		var var = obj;
	}
}

As you can see in the above code, var can be used as a variable type when the right hand side of the assignment infers the dataype. Also, one more thing to remember, var can be used as a variable name as well, since it is not a keyword.

There are some restrictions in the way we can use var. Lets have a look at some of the ways var cannot be used.

import com.maxCode.online.longPackageName.var.AnyRandomClassWithAVeryLongName;

public class InvalidVars {
    static var anyVar = 4;  //cannot use var in class variables

	public static void main(String[] args) {
		//cannot use var declaration in compound statement
		var j = 0, k = 0;
		var m, n = 0;
		
		//Cannot declare var without initializing it
		var anyObject;
		
		//Cannot assign null as type cannot be inferred
		var var = null;
		
		//Cannot use array initializer
		var varArr = {"A", "Z"};
		
		//Cannot have a var array
		var[] anotherVarArr = new int[5];
	}
}

As we have already discussed, var is only for local variables, hence first line is invalid. var j = 0, k = 0; line will give compile time error stating “var is not allowed in a compound declaration”. Below that, we havent initialized one variable so it is invalid. Same for the one below. We cannot assign null or use array initializer in var declaration, as in the last examples.

Along with these, we also cannot use var for method parameters or method return types. Something like below will give compile time error.

public static var anyMethod(String[] test) {
    return test;
}

public static String[] anotherMethod(var var) {
    return var;
}

Note: Java 11 has introduced LVTI for Lambda expressions, which we will cover in later sections.

We can use var in loop variables as long as the variable type can be inferred. In the below code, i can be inferred to int by initialization int i = 0 and arg to String, and so its valid.

import com.maxCode.online.longPackageName.var.AnyRandomClassWithAVeryLongName;

public class InvalidVars {
	public static void main(String[] args) {
		for (var i =0; i < 10; i++) {
			System.out.println("i value is : " + i);
		}
		
		for (var arg: args) {
			System.out.println("arg value is : " + arg);
        }
        
        //Some more valid var initializations
        var a = 1;  //inferred to int
        var b = 5.0f/2; //inferred to float
        
        short s = 1;
        var c = +s; //c will be inferred to int since '+' operator forces s to promote to int

        var list = new ArrayList<>();   //okay since ArrayList can be initialized without type
        var myArr = new String[5];  //good to use
	}
}

So to sum up the above discussion, var cannot be used for

  • class or instance variables
  • method return types
  • method parameters
  • constructor parameters

var can be used for

  • local variables in methods and code blocks,
  • loop variables

Thats all for Local Variable Type Inference or LVTI or var.