Pages

Footer Pages

Spring Boot

Java String API

Java Conversions

Kotlin Programs

Kotlin Conversions

Java Threads Tutorial

Java 8 Tutorial

Thursday, May 2, 2019

Java 10 LVTI: Local Variable Type Inference Explained with Examples

Java 10 Local Variable Type Inference:

In this tutorial, We will learn what is Java 10 Local Variable Type Inference with examples.

Introduction:

Java 10 introduced a new shiny language feature called local variable type inference and One of the most obvious enhancements in JDK 10.
Type inference refers to the automatic detection of the datatype of a variable, done generally at the compiler time.

For the local variables, we can use a special reserved type "var" instead of actual type and var is not a keyword. This enhancement helps in reducing the boilerplate code.

Java 10 LVTI - Local Variable Type Inference Explained with Examples

Before java 10:

Untill Java 9 or before its version, we must have to declare the type of local variable explicitly and to initialize its value. See below compiled code snippet.

String byeNote = "Saying Good Bye to Java 9 local variables";

Introduction in java 10:

The same above code can be rewritten as below with var.

var byeNote = "Saying Good Bye to Java 9 local variables";

Observe here that right side value type is String and compiler infers the type of byeNote variable based on the right side value. So, We no need to provide the actual type.

Java authors realized that right side already type is available and why again need to mention at the left side. Hence, introduced this new concept.

In the above case, the type of byeNote is String.

Rule:

This feature is available only for the local variables with a mandatory initializer. This can not be used with instance variables, static variables, method parameters, return types etc.

Initializing the variable with a value is must, otherwise compiler can not infer the type.

Note:

Some of the people think, This will be done at run-time which is determined dynamically and usage of var will cause for the overhead to the performance.
No. This statement is wrong. Because type inference is determined at compile time.


Example on var before and after java 10:

We will see another example in before and after Java 10.

Java 9:

 // Java code for Normal local variable declaration 
import java.util.ArrayList; 
import java.util.List; 
class A { 
    public static void main(String ap[]) 
    { 
       List data = new ArrayList();
    } 

Java 10:

This code works only in Java 10 or above versions.

 var data = new ArrayList();

Var can be used in the following cases and all are valid in java 10. Tested the code.

Case 1: Static block

 static {
  var car = new Car();
 }

Case 2: Local variable

 public String getStatus() {
  var str = "Success";
  return str;
 }

Case 3: Enhanced for each loop variable


  var data = new ArrayList();
  data.add("local");
  data.add("type");

  for (String s : data) {
   System.out.println(data);
  } 

Case 4: For loop index

for (var i = 0; i < data.size(); i++) {
 System.out.println(data.get(i));
} 

Case 5: Retuned value of method

// storing getStatus method returnted value into var variable.
  var value = getStatus();
 public static String getStatus() {
      var str = "Success";
      return str; }

Illegal usage of var:

var is a keyword that can't be used in the many possible areas. we'll discuss all the areas now.

1) Without an explicit initialisation

We can't utilize local variable declarations without an explicit initialisation. This means, you cannot simply use the var syntax to declare a variable without a value. The following is invalid.

  var y;

Error:
 Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
 Cannot use 'var' on variable without initializer

 at examples.java.w3schools.java10.local.LocalVariable.main(LocalVariable.java:35)

2) Reiniatializing

 var n = 6;
 n = "six"; 

Error:

 Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
 Type mismatch: cannot convert from String to int

 at examples.java.w3schools.java10.local.LocalVariable.main(LocalVariable.java:33)
 
Here, var n is intialized with 6 which is a number and later reinitialized with String "six". This is illegal because change in type from int to String that means it can't convert String to int.   

3) var variable to null

Can't initialise a var variable to null either because null does not specify the type of the value. So this is also an illegal case.

var y = null;

Error:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
 Cannot infer type for local variable initialized to 'null' 

4) On method signatures:

    a) on method arguments:

 public void printNumber(var num) {
         System.out.println(num);
 }
 
Simply compiler will say "var is not allowed here". The following is the output when we execute this program.

    Error:

 Error: Unable to initialize main class examples.java.w3schools.java10.local.LocalVariable
        Caused by: java.lang.NoClassDefFoundError: var
 

    Saying it is not able to find the any class named with "var"

    b) on method return type

 public var printNumber(int num) {
  System.out.println(num);
 } 
 
      This is also similar to the above case (a).

Best Practices to avoid usage of Var:

There are circumstances where var can be utilized legally, however may not be a smart choice to do as such.

Practice 1: Method return area

For instance, in circumstances where the code could turn out to be less meaningful:

var status = obj.prcoessMessages();

Here, the above code looks good but makes less readable what prcoessMessages() method is returning.

Practice 2: Long steam pipeline

Here, we start with a Stream<Employee> and get an IntStream by supplying the Employee::getId to mapToInt. Finally, we call max() which returns the highest integer.

var latestEmpId = empList.stream()
   .mapToInt(Employee::getId)
   .max()
   .orElseThrow(NoSuchElementException::new);

This is the another place where it’s best to avoid var is in streams with long pipeline.

Practice 3: With the diamond operator

Diamond operator is introduced in java 7 which can cause to the unexpected result using var in below code.

var studentList = new ArrayList<>();

This code is still valid and it looks to take ArrayList<Object> that means we can add any value to the studentList as below.

studentList.add(new Student(100));
studentList.add("second");
studentList.add(new Car()); 

Able to add Student object, String object and Car object to the studentList. This is better to avoid usage in this case.

If we want to add only Student instances then declaration must be changed to

var studentList = new ArrayList();

Practice 4: non-denotable types (Anonymmous instances)

Must be careful while dealing with non-denotable instances.

var obj = new Object() {
 String name = "java";
}; 

Here created an object for anonymus class and storing the object in var obj.

If we try to reassign to new Object() then will get compile time error.

obj = new Object(); 

Error:

 Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
 Type mismatch: cannot convert from Object to new Object(){}

This is because the inferred type of obj isn’t Object.

Conclusion:

In this tutorial, we saw the new Java 10 local variable type inference feature with examples and best practices. var is a pretty nice little addition to the Java language in terms of productivity and readability, but the fun doesn’t stop there. But here missing is usage of var in lamda expressions.

All the example programs shown in this tutorial are on GitHub

No comments:

Post a Comment

Please do not add any spam links in the comments section.