Skip to main content

Local variable type inference : Welcome 'var' in Java

Yes, you read it right. ‘var’ is now available for Java developers as well. JDK 10 which got released on March 20th, 2018 rolled out a shiny feature which allows developers to use var for declaring local variables.
We all know that Java is static typed language. But wait a minute, does this inclusion of var now make Java a dynamic typed language? As we know JavaScript allows to define variables using var and it is indeed dynamically typed language.

Quick refresher of static and dynamic types:
Static type Types cannot change at runtime. For example, below java code will not compile
int myvar = 1;
myvar = “Toyota”;
myvar = ["Saab", "Volvo", "BMW"];
Dynamic type – Types can change at run time. For example, below code in JavaScript is valid
var myvar;
myvar = 1;
myvar = “Toyota”;
myvar = ["Saab", "Volvo", "BMW"];

So to answer the question “Does this inclusion of var now make Java a dynamic typed language?” Answer is NO. Java remains to be static typed language and to be so there will be set of guidelines defined for usage of var. Developers will be allowed to use var within those defined boundaries so that compiler can infer the type of variable defined using var.
So at this point we know that Java allows to use var and Java still remains static typed language. Before understanding how and when var can be used let’s take a step back and see a bit of type inference history.

"Type inference" is the idea that the compiler can figure out the static types for you so you don’t have to type them. Primary use of it is to “Allow developers to write concise code”.
In Java 5 type parameter of generics methods can be inferred based on the context,
For example, In order to invoke emptyList method in Collections class
public static final <T> List<T> emptyList()

Instead of
List<String> cs = Collections.<String>emptyList();
You can say:
List<String> cs = Collections.emptyList();

In Java 7, diamond operator allowed to omit type parameters of generics in an expression when the context determines them. For example,
Map<String, List<String>> myMap = new HashMap<String,List<String>>();
can be abbreviated to the following by making use of the diamond <> operator:
Map<String, List<String>> myMap = new HashMap<>();
The general idea is that the compiler can infer the type based on surrounding context. In this case the HashMap contains a list of strings as indicated on the left-hand side.

In Java 8, lambda expressions such as
Predicate<String> validateResult = (String x) -> x.length() > 0;
can be shortened by omitting types
Predicate<String> validateResult = x -> x.length() > 0;

Ok enough of history, let’s come back to present and discuss about inclusion of var in Java.
JDK 10 included JEP 286 (Local variable type inference) which aims to enhance the Java Language by extending type inference to declarations of local variables with initializers. Its principal goal is to reduce boilerplate and enhance code readability. It enables us to replace the type in a local variable declaration with the keyword var— and then it is compiler’s job to fill in the appropriate type from the variable initializer.
For example,
Instead of this
Map<String, Integer> x = new HashMap<String, Integer> ();
You can say,
var myMap = new HashMap<String, Integer>();
myMap in above expression still has static type. Compiler is able to infer that is it of type Map<String, Integer> from RHS declaration. Since it is static type we cannot assign anything else to it. After above declaration below code will give error and won’t compile,
myMap = “trying to change type to string”;



Let’s now talk about where n all we can use var

It can be used only for,
  • Local variables with initializers
  • Indexes in the enhanced for-loop
  • Locals declared in a traditional for-loop
For example:


Where Can’t You Use Local Variable Type Inference?
It would not be available for following:

  • Method formals

  • Constructor formals

  • Method return types
  • Fields
  • Catch formals

Or any other kind of variable declaration
  • You cannot use local variable declarations without an explicit initialization. This means you cannot just use the var syntax to declare a variable without a value
  • Cannot initialize a var variable to null
  • Cannot use var with lambda expressions, because lambdas require an explicit target type




Conclusion

Intent of type inference is always to write concise code and remove boilerplate. Inclusion of var in the language is just an addition to that. var is definitely a helpful addition to the language in terms of productivity and readability as it will allow developers to exclude ceremony involved with writing types for local variables. 
Other JVM languages like scala, C#, Go etc already support some form of local variable type inference so this is definitely welcomed addition in Java language.

Comments

Post a Comment