Saturday, 15 June 2019

Java10: var: Local Variable Type Inference


From java10 onwards you no need to explicitly declare the type of local variables.

You can write using ‘var’ like below.
var a = 10;

Type of local variable is inferred by the compiler.

public static void demoFunction(){
    var a = 10;

    System.out.println("a : " + a);
}

For example, in the above function, I defined a variable ‘a’ using var keyword.  Type of the variable is inferred by the compiler from the right hand side expression.

var is not a keyword in Java?
‘var’ is not a keyword, but it is a reserved type name. This means that code that uses var as a variable, method, or package name will not be affected; code that uses var as a class or interface name will be affected (but these names are rare in practice, since they violate usual naming conventions).

In Java, keywords are not used as identifiers or variable names. Since ‘var’ is not a keyword, you can use it as variable name too.

public static void demoFunction(){
         var var = 10;
        
         System.out.println("var : " + var);
}

Since var is not a keyword, you can use ‘var’ as a method name, parameters name, package name etc.,

Type inference is only for local variables
You can’t use ‘var’ on instance properties, return types, method parameters etc.,

Main.java
package com.sample.app;

public class Main {

      public static void demoFunction(){
            var a = 10;

            var var = 11; // You can use var as a variable name

            System.out.println("a : " + a);
            System.out.println("var : " + var);

            //You can use var in a for loop.
            for(var i = 0; i < 10; i++){
                  System.out.print(i + " ");
            }
            System.out.println();

            //You can use var while defining array
            var primes = new int[] {2, 3, 5, 7};
            for(var i : primes){
                        System.out.print(i + " ");
            }
            System.out.println();

      }

      public static void main(String args[]) {

            demoFunction();

      }
}

Output
a : 10
var : 11
0 1 2 3 4 5 6 7 8 9
2 3 5 7

You can get the complete working module at below location.

Use below commands to compile and run the application.

javac --module-source-path src -d out src/printdata/com/sample/app/Main.java

java --module-path out -m printdata/com.sample.app.Main


Does var turns Java into a dynamic language like JavaScript or Python?
No. When you compile a java program, down the line it infers the types and places it in the byte code.


Main.java
package com.sample.app;

public class Main {

      public static void demoFunction() {
            var a = 10;
            a = "Hello World";

            System.out.println("a : " + a);
      }

      public static void main(String args[]) {

            demoFunction();

      }
}

As you see above example, I assigned a with value 10 and I again reassigned the string "Hello World" to the variable a.


When I try to compile Main.java application, I end up in below compiler error.
$javac --module-source-path src -d out src/printdata/com/sample/app/Main.java
src/printdata/com/sample/app/Main.java:8: error: incompatible types: String cannot be converted to int
            a = "Hello World";
                ^
1 error

Limitations of var
a. Java compiler can’t infer a type for null
If you declare below statement in your application, compiler can’t infer the type.
var a = null;


Main.java
package com.sample.app;

public class Main {

      public static void main(String args[]) {

            var a = null;

      }
}


When you try to compile Main.java, you will end up in below error.

$javac --module-source-path src -d out src/printdata/com/sample/app/Main.java
src/printdata/com/sample/app/Main.java:8: error: cannot infer type for local variable a
            var a = null;
                ^
  (variable initializer is 'null')
1 error

b. When you use ‘var’ for a generic collection, it infers to Object.
var hobbies = new ArrayList<> ();

In the above example, new ArrayList<>() would infer the type as ArrayList<Object>

var map1 = new HashMap(); // Inferred as HashMap
var map2 = new HashMap<>(); // Inferred as HashMap<Object, Object>

But if you explicitly specify the type in <>, then java infers the type.
var list = new ArrayList<String>();  // infers ArrayList<String>

c. You can’t use var on variables without initializer
If you declare a variable like below, java compile can’t infer the type.
var a;


Main.java
package com.sample.app;

public class Main {

      public static void main(String args[]) {
            var i;
      }
}


When you try to compile above program, you will end up in below error.

$javac --module-source-path src -d out src/printdata/com/sample/app/Main.java
src/printdata/com/sample/app/Main.java:7: error: cannot infer type for local variable i
            var i;
                ^
  (cannot use 'var' on variable without initializer)
1 error

d. You can’t use ‘var’ to define multiple variables.
var i = 10, j = 20;


Main.java
package com.sample.app;

public class Main {

      public static void main(String args[]) {
            var i = 10, j = 20;
      }
}


When you try to compile above program, you will end up in below error.

$javac --module-source-path src -d out src/printdata/com/sample/app/Main.java
src/printdata/com/sample/app/Main.java:7: error: cannot infer type for local variable i
            var i;
                ^
  (cannot use 'var' on variable without initializer)
1 error

e. lambda expression needs an explicit target-type
Main.java:10: error: cannot infer type for local
variable f
        var f = () -> { };
            ^
  (lambda expression needs an explicit target-type)

f. Array initializer needs an explicit target-type
Main.java:10: error: cannot infer type for local variable k
        var k = { 1 , 2 };
            ^
  (array initializer needs an explicit target-type)

Reference



Previous                                                 Next                                                 Home

No comments:

Post a Comment