Local Variable Type Inference in Java 10

04.05.2018 -

The Local Variable Type Inference is certainly the feature Java 10 is known for - similar to Generics in Java 5, or Lambdas and Streams in Java 8.

Java 10 is now over a month old again. So it's high time to take a closer look at what is probably the most important feature of the release.

What is it all about?

Essentially, the possibility of omitting the type when declaring local variables. Instead of specifying a type, simply write var.

Incidentally, this only works in local scopes, i.e. within methods or blocks, but not with class variables or method parameters. Hence the name Local Variable Type Inference.

A few examples:

var hello = "Hello World!";
var answer = 42;
var pi = 3.14159;
var notTrue = false;
var list = List.of("abc");
var anotherList = new ArrayList<Integer>();

What does that mean? 

Quite simply: the compiler derives the type from the initialization expression so that you no longer have to explicitly write the type on the left-hand side of the equals sign. This means: The variable hello from the example above is given the type string, the variable answer is given the primitive data type int, pi is of type double, notTrue is a boolean.

Die Variable list bekommt den Typ List; anotherList dagegen den Typ ArrayList<Integer>. Letzteres bedeutet, dass man in Folge auch anotherList.ensureCapacity(42); schreiben kann! Hier wird also eine Methode aufgerufen, die es nur in ArrayList gibt, aber nicht im List-Interface oder anderen List-Implementierungen.

Is that bad? Usually you use the interface as a type so that you are not bound to a specific implementation. In the case of var, however, this is acceptable because the whole thing takes place in a very limited scope (keyword "local"), and changing the implementation would therefore mean a fairly manageable amount of work.

What does it not mean?

First of all, you might assume that var is a new keyword. But it is not. That's why the following also works:

var var = "a variable named var";
System.out.println(var);

So you don't have to worry that existing code from earlier versions will no longer compile with Java 10 if variables with the name var appear there. Backwards compatibility is therefore guaranteed.

Furthermore, it does not mean that var introduces dynamic typing in Java. Developers who have a lot to do with JavaScript could easily get this impression. However, Java is and remains a strictly typed language, and the var feature does not change this.

What about val?

Anyone familiar with Scala may now be wondering whether val has been introduced in addition to var. In Scala, val is used to define constants, i.e. "variables" whose value may no longer change after initialization. This was also considered during the implementation of the feature, but it was decided against it, so that for unchangeable values in Java final var is used for immutable values in Java.

A few subtleties

Der „Diamond-Operator“ <> sollte im Zusammenhang mit var nicht verwendet werden. Die Deklaration var list = new ArrayList<>(); resultiert nämlich im Typ ArrayList<Object>. Gleichermaßen ergibt var list = List.of() den Typ List<Object>, sowie var opt = Optional.empty(); den Typ Optional<Object>.

What does not work:

var nil = null;    // kompiliert nicht -> von null kann kein Typ abgeleitet werden
var uninitialized; // kompiliert nicht -> die Initialisierung muss immer zusammen mit der Deklaration erfolgen
var x = 0, y = 1;  // kompiliert nicht -> Mehrfachdeklaration u. -Initialisierung ist nicht möglich

Which used to be impossible:

var person = new Object() {
   String name = "Arthur";
   int age = 42;
};
System.out.println(person.name + " aged " + person.age);

Before Java 10, you had to declare the person object with the object type. This meant that the possibility of accessing the name and age fields was lost. With var, you get an extended type that also contains the two fields, which can therefore also be accessed from outside. However, a practical use for this was not really clear to me.

When do I use var?

Now to the crucial question - should you use var or not? As always, this cannot be answered with a blanket yes or no. This must be decided on a case-by-case basis. The rule of thumb should be Yes, if it improves the readability and comprehensibility of the code. No, if the code is easier to understand with an explicit type specification.

As a guideline, there is a style guide that uses examples to explain when it makes sense to use var and when not:
http://openjdk.java.net/projects/amber

Back to overview

Write a comment

Your e-mail address will not be published. Required fields are marked with *

*Mandatory fields

*