Java 10 + var = L.F.E.

New variable type named ‘var’ in Java 10? Have we started turning into JavaScript anarchists? Has its very substance been polluted by Kotlin enthusiasts? Should we all worry by this new “feature” (are we sure its not a bug?) or could there be any benefits from using ‘var’ in our code?

Var is used for type inference in Java and helps reduce the verbosity of the language. This means you are able to omit variables’ type, as it will be inferred by the compiler by looking at the right hand part of the assignment. To make things a bit clearer checkout the following example:

Since Java 10 the following declaration

String firstName = "Iakovos";

is the same as:

var firstName = "Iakovos";

Compiler detects that the value on the right is of type String and without explicitly making the declaration, it infers the ‘firstName’ type. Meaning firstName is instanceof String.

You might think that var is a reserved keyword but that’s not the case since doing so would break backwards compatibility, instead it is a reserved type name just like int, long, double etc. .

Type inference is not new, since it was first introduced with Java 7

List<String> currencyList = new ArrayList<>();

instead of Java 6 and prior

List<String> currencyList = new ArrayList<String>();

Then we saw it in Java 8

Prior to java 8
Predicate<String> authorList = (String authors) -> authors.contains("Iakovos");

Java 8 onwards
Predicate<String> authorList = authors -> authors.contains("Iakovos");

Common QA would go something like this:

  • What is the scope of the variable? Can you also have class variables of type var?

No, absolutely not, only method scope.

  • Is it necessary to initialize var with a value all the time?

Yes the following is forbidden

 var firstName = null

A simple rule to remember, is that the compiler should be able to infer the variable type when it is declared. For this to happen, it looks at the value on the right to get some clues. In the example above someone would argue the case of assigning type Object to firstName, but that would be too vague and without a point as everything derives from Object type, var included. Also that would mean that java is not a statically typed language anymore.

  • OK, so how will this piece of code actually help us?

When using it we reduce verbosity from type declarations as shown below.

ex.
var nameAppender = new StringBuffer();
var delimiter = "+";
var endingCharacter = "-";
  • Will it cause any confusions?

Well it can, but that highly depends on the way you code.

ex.
var prettinessLevel = myPrettyClass.increasePrettiness(1);

or maybe something like..

var result = myPrettyMethod();

In any case, var like most things in life can be a knife. You can either write sexier code or make other people’s eyes bleed.

  • If I initialize var with String, can I then go ahead and reassign a value of type int?

Nope doing something like var name = "Iakovos"; and then reassign name = 3; will fail with compilation error. Upon initialization var has type String and that cannot change later in the code, meaning type safety is intact (in other words no, Java hasn’t turned into JavaScript).

  • How is var represented in my generated.class files?

Well if you run decompiler ex. javap -c main.class for your classes you will see that the generated types don’t include var but the infer types instead.

  • Can you declare an array of type var?

Nope doing so won’t work. Trying it out on IntelliJ IDEA, I received the following error: Array initializer is not allowed here

//won't work!
var t = {1,2};
  • When you assign an arithmetic value to a variable of type var, how will it be autoboxed?

Good question, let see what happens. If you have a small value lets say 1, var will be of type int not short. Now, if you try something like var a = Integer.MAX_VALUE + 15; variable ‘a’ won’t be autoboxed to long, but will be of type int instead and an overflow will occur. Meaning ‘a’ will have a value of -2147483634

Playing around a bit with Intellij I found the following:

  • Classes with name var are prohibited
  • Interfaces with name var are prohibited
  • You can declare a method with name var
//don't try this at home
 var x = var();

public static int var(){
    return 1;
}
  • You can declare a variable with name var
 String var = "2";
  • You can declare a package named var //for the love of God don’t..

If you want o see the var feature in more depth, please check out this article from Oracle. Apart from being very educational there is a great section on how to use “Type Inference with Non-Denotable Types”.