Local Variables Type Inference in Java
Tags: java
Published: 2019-01-01 09:46:24

---
title: Local Variables Type Inference in Java
published: true
description: An Enhanced Type Inference for only local variables.
tags: java
---
To be short, This post is about a type called **var**, which is introduced in java 10. Before started using var type, i have analysed and summarised about where to use and not to use var type like as an argument for methods, constructors, Exceptions, lambdas, Streams, etc...

**var** - Type Inference for local variables.

Before start using var, we need to understand few questions.

**What is var ? what is the use of it ?**

It is used to declare local variables and reduces the boilerplate code.

**Is it a new keyword introduced in java ?**

The answer is big **No**, it is not a keyword, a new type called var has created to improve type inference. 

**Is java becoming dynamic type language like JavaScript ?**

**No**, Added an intelligent for compiler to understand the type of the local variable using its initializer without specifying explicitly.

**How are the possible ways to declare local variables?**

Examples:-


```
List<String> list = new ArrayList<String>(); // level 1
List<String> list = new ArrayList<>(); // level 2
var list = new ArrayList<String>(); // level 3
```


There are the places to use and not to use. Lets see few of that.


<table>
  <tr>
   <td>Scenario
   </td>
   <td>Example
   </td>
  </tr>
  <tr>
   <td>Cannot use var without initializer.
   </td>
   <td><code>jshell> var a;</code>
<p>
<code>|  Error:</code>
<p>
<code>|  cannot infer type for local variable a</code>
<p>
<code>|	(cannot use 'var' on variable without initializer)</code>
<p>
<code>|  var a;</code>
   </td>
  </tr>
  <tr>
   <td>Cannot initialize with null.
   </td>
   <td><code>jshell> var a=null</code>
<p>
<code>|  Error:</code>
<p>
<code>|  cannot infer type for local variable a</code>
<p>
<code>|	(variable initializer is 'null')</code>
<p>
<code>|  var a=null;</code>
<p>
<code>|  ^---------^</code>
   </td>
  </tr>
  <tr>
   <td>Cannot use with arrays
   </td>
   <td><code>jshell> var[] a = new int[]{1,2,3}</code>
<p>
<code>|  Error:</code>
<p>
<code>|  'var' is not allowed as an element type of an array</code>
   </td>
  </tr>
  <tr>
   <td>Cannot use Multi variable declarations
   </td>
   <td><code>jshell> var a = "Alpha",b="Beta",c="Gamma";</code>
<p>
<code>|  Error:</code>
<p>
<code>|  'var' is not allowed in a compound declaration</code>
<p>
<code>|  var a = "Alpha",b="Beta",c="Gamma";</code>
<p>
<code>|              	^</code>
<p>
<code>|  Error:</code>
<p>
<code>|  'var' is not allowed in a compound declaration</code>
<p>
<code>|  var a = "Alpha",b="Beta",c="Gamma";</code>
   </td>
  </tr>
  <tr>
   <td>Variables, methods can be named var.
   </td>
   <td><code>jshell> var var = "Hello World!!!"</code>
<p>
<code>var ==> "Hello World!!!"</code>
<p>
<code>jshell> /l var</code>
<p>
<code>   1 : var var = "Hello World!!!";</code>
<p>
<code>jshell> public void var() { System.out.println("Hello world!!!");}</code>
<p>
<code>|  created method var()</code>
<p>
<code>jshell> var()</code>
<p>
<code>Hello world!!!</code>
   </td>
  </tr>
  <tr>
   <td>Classes and Interfaces can't be named var
   </td>
   <td><code>jshell> class var {}</code>
<p>
<code>|  Error:</code>
<p>
<code>|  'var' not allowed here</code>
<p>
<code>|	as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations</code>
<p>
<code>|  class var {}</code>
<p>
<code>|    	^</code>
<p>
<code>jshell> interface var {}</code>
<p>
<code>|  Error:</code>
<p>
<code>|  'var' not allowed here</code>
<p>
<code>|	as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations</code>
<p>
<code>|  interface var {}</code>
<p>
<code>|        	^</code>
   </td>
  </tr>
  <tr>
   <td>Can be used with collections
   </td>
   <td><code>jshell> var list = List.of("alpha","beta","gamma");</code>
<p>
<code>list ==> [alpha, beta, gamma]</code>
<p>
<code>jshell> /v list</code>
<p>
<code>|	List<String> list = [alpha, beta, gamma]</code>
<p>
<code>jshell> var set = Set.of("alpha","beta","gamma");</code>
<p>
<code>set ==> [beta, gamma, alpha]</code>
<p>
<code>jshell> /v set</code>
<p>
<code>|	Set<String> set = [beta, gamma, alpha]</code>
<p>
<code>jshell> var map = Map.of(Map.entry("name","PrabuSubra"),Map.entry("city","Bangalore"))</code>
<p>
<code>map ==> {name=PrabuSubra=city=Bangalore}</code>
<p>
<code>jshell> /v map</code>
<p>
<code>|	Map<Map.Entry<String,String>,Map.Entry<String,String>> map = {name=PrabuSubra=city=Bangalore}</code>
   </td>
  </tr>
  <tr>
   <td>Cannot use in method/Constructor arguments
   </td>
   <td><code>jshell> public void displayError(var errorMessage) { System.out.println(" Error due to : "+errorMessage);}</code>
<p>
<code>|  Error:</code>
<p>
<code>|  'var' is not allowed here</code>
<p>
<code>|  public void displayError(var errorMessage) { System.out.println(" Error due to : "+errorMessage);}</code>
<p>
<code>|                       	^-^</code>
   </td>
  </tr>
  <tr>
   <td>Cannot used as return type in method signature.
   </td>
   <td><code>jshell> public var displayError(String errorMessage) { return "Error due to : "+errorMessage;}</code>
<p>
<code>|  Error:</code>
<p>
<code>|  'var' is not allowed here</code>
<p>
<code>|  public var displayError(String errorMessage) { return "Error due to : "+errorMessage;}</code>
<p>
<code>|     	^-^</code>
   </td>
  </tr>
  <tr>
   <td>Can be used in loops.
   </td>
   <td><code>jshell> for(var templist : list){   System.out.println(templist);</code>
<p>
<code>}</code>
<p>
<code>for(var i = 0;i<list.size();i++){ System.out.println(list.get(i));</code>
<p>
<code>}</code>
   </td>
  </tr>
  <tr>
   <td>Can be used with Streams
   </td>
   <td><code>shell> var streams = Stream.of("alpha","Beta","Gamme","delta","Epsilon");</code>
<p>
<code>streams ==> java.util.stream.ReferencePipeline$Head@1bce4f0a</code>
<p>
<code>jshell> /v streams</code>
<p>
<code>|	Stream<String> streams = java.util.stream.ReferencePipeline$Head@1bce4f0a</code>
   </td>
  </tr>
  <tr>
   <td>Cannot assigned Functional interfaces to it.
   </td>
   <td><code>jshell> var function = (data)->data</code>
<p>
<code>|  Error:</code>
<p>
<code>|  cannot infer type for local variable function</code>
<p>
<code>|	(lambda expression needs an explicit target-type)</code>
<p>
<code>|  var function = (data)->data;</code>
<p>
<code>|  ^--------------------------^</code>
<p>
<code>jshell> var consumer = (data)->{}</code>
<p>
<code>|  Error:</code>
<p>
<code>|  cannot infer type for local variable consumer</code>
<p>
<code>|	(lambda expression needs an explicit target-type)</code>
<p>
<code>|  var consumer = (data)->{};</code>
<p>
<code>|  ^------------------------^</code>
<p>
<code>jshell> var supplier = ()->{return new String("Hello world!!!");}</code>
<p>
<code>|  Error:</code>
<p>
<code>|  cannot infer type for local variable supplier</code>
<p>
<code>|	(lambda expression needs an explicit target-type)</code>
<p>
<code>|  var supplier = ()->{return new String("Hello world!!!");};</code>
<p>
<code>|  ^--------------------------------------------------------^</code>
<p>
<code>jshell> var runnable = ()->{}</code>
<p>
<code>|  Error:</code>
<p>
<code>|  cannot infer type for local variable runnable</code>
<p>
<code>|	(lambda expression needs an explicit target-type)</code>
<p>
<code>|  var runnable = ()->{};</code>
<p>
<code>|  ^--------------------^</code>
   </td>
  </tr>
  <tr>
   <td>Cannot use with Exception handlers
   </td>
   <td><code>jshell> try { } catch (var e){}</code>
<p>
<code>|  Error:</code>
<p>
<code>|  'var' is not allowed here</code>
<p>
<code>|  try { } catch (var e){}</code>
<p>
<code>|             	^-^</code>
   </td>
  </tr>
  <tr>
   <td>Cannot assign to interface, it always reference to initializer type.
   </td>
   <td><code>jshell> var list = new ArrayList<String>()</code>
<p>
<code>list ==> []</code>
<p>
<code>jshell> /v list</code>
<p>
<code>|    ArrayList<String> list = []</code>
<p>
<code>jshell></code>
   </td>
  </tr>
  <tr>
   <td>Cannot used with type inference.
   </td>
   <td><code>jshell> class Alpha <var> { var t;}</code>
<p>
<code>|  Error:</code>
<p>
<code>|  'var' not allowed here</code>
<p>
<code>|    as of release 10, 'var' is a restricted local variable type and cannot be used for type declarations</code>
<p>
<code>|  class Alpha <var> { var t;}</code>
<p>
<code>|               ^</code>
<p>
<code>|  Error:</code>
<p>
<code>|  'var' is not allowed here</code>
<p>
<code>|  class Alpha <var> { var t;}</code>
<p>
<code>|                      ^-^</code>
   </td>
  </tr>
</table>


Law of var:-
    Properly initialised, Non-array variables can use the luxury of var type inference.

Summary:-
    Eventually, Java has added few spoon of sugar to existing Type Inference feature. it is not completely freed developers hands to use var in code, it comes with its own laws. Type inference is not completely new feature in java, it has improved a step to use for local variables,mostly to avoid boilerplate code with less upgrade hurdles. The target source code base shouldn't contains class or interface, which was named as var and possibility also rare, nearly nothing. It is one of the way(not only way) to declare local variables.

Reference:-

[http://openjdk.java.net/jeps/286](http://openjdk.java.net/jeps/286)

[https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html](https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html)

[https://github.com/prabusubra/Learning/blob/master/Java/JShell/jshell.txt](https://github.com/prabusubra/Learning/blob/master/Java/JShell/jshell.txt)

Note:- if you feel something has to be added or wrong, feel free to comment below. Thanks for reading!!!