Var and Language Design in Java
Learn everything you need to know about var in Java.
Join the DZone community and get the full member experience.
Join For FreeWhat Is Var in Java
The var predefined type introduced in Java 10 lets you declare local variables without specifying the variable type when you assign a value to it. When you assign a value to a variable, the expression type already defines the variable type, leaving no reason to specify the type on the left side of the line again. Thus, there is no reason to type the expression on the left side of the line again. It is especially good when you have complex, long types with a lot of generics, for example:
HashMap<String,TreeMap<Integer,String> myMap = mapGenerator()
Generic types could already be inherited in prior Java versions, but now, you can simply type:
var myMap = mapGenerator();
This is much simpler, and most of the time, this is more readable than previous versions. The aim of the var
is mainly readability. It is important to understand that the variables declared this way will have a type and the introduction of this new predefined type (not a keyword) does not render Java to be a dynamic language. There are a few things that you can do that you could not do before, or you could do it but in a more verbose way. For example, when you assign an instance of an anonymous class to a variable, you can invoke the declared methods in the class through the var
declared variables. For example:
var m = new Object{ void z(){} }
m.z();
You can invoke the method z()
but the code:
Object m = new Object{ void z(){} }
m.z();
... does not compile. You can do that because anonymous classes actually have a name at their birth; they just lose it when the instance gets assigned to a variable declared the type of Object
.
There is a little shady part of the var
keyword. This way, we violate the general rule to instantiate the concrete class but declare the variable as the interface. This is a general abstraction rule that we usually follow in Java. When I create a method that returns a HashMap
, I usually declare the return value to be a Map
. That is because HashMap
is the implementation of the return value and, as such, is none of the business of the caller. What I declare in the return type is that I return something that implements the Map
interface. The way I do it is my own duty. Similarly, we usually declare the fields in the classes to be of some interface type, if possible. The same rule should be followed by local variables. A few times, it has helped me when I declare a local variable to be Set
but the actual value was TreeSet,
and then, when typing the code, I faced some errors. Then, I realized that I was using some of the features that are not Set
but SortedSet
. It helped me realize that sorted-ness is important in the special case and that it will also be important for the caller, and thus, I had to change the return type of the method to be SortedSet
. Note that SortedSet
in this example is still an interface and not the implementation class.
With the use of var
, we lose that and we gain a somewhat simpler source code. It is a trade-off, as always. In case of the local variables, the use of the variable is close in terms of source code lines to the declaration; therefore, the developer can see a glimpse into what is what and what is happening. Therefore, the “bad” side of this tradeoff is acceptable. The same tradeoff in case of method return values or fields is not acceptable. The use of these class members can be in different classes and modules. It is not only difficult, but it may be impossible to see all of the uses of these values. Therefore, we continue with the good, old way: declare the type.
The Future of Var
There are cases when you cannot use var
, even for local variables. Many times, we have the following coding pattern:
final var variable; // this does not work in Java 11
if ( some condition ) {
variable = expression_1
// do something here
} else {
variable = expression_2
// do something here
}
Here, we can not use var
because there is no expression assigned to the variable on the declaration itself. The compiler, however, could be extended. From now on, when I talk about Java, I am not talking about it as it is now. I am discussing what I imagine it to be in future versions.
If the structure is simple and the “do something here” is empty, then the structure can be transformed into a ternary operator:
final var variable = some condition ? ( expression_1 ) : (expression_2)
In this case, we can use the var
declaration, even if we use an old version of Java, e.g. Java 11. However, be careful!
var h = true ? 1L : 3.3;
What will be the actual type of the variable h
in this example? Number
? The ternary operator has complex and special type coercion rules, which usually do not cause any issue because the two expressions are close to each other. If we let the structure described above use a similar type coercion, then the expressions are not that close to each other. As for now, the distance is far enough for Java not to allow the use of the var
type definition. My personal opinion is that the var
declaration should be extended sometime in the future to allow the above structure, but only in the case when the two (or more in case of a more complex structure) expressions have exactly the same type. Otherwise, we may end up having an expression that results in an int
, another that results in a String,
and then what will the type of the variable be? Do not peek at the picture before answering!
(This great example was given by Nicolai Parlog)
I can also imagine that, in the future, we will have something similar to Scala val
, which is final var
in Java 11. I do not like the var
vs. val
naming though. It is extremely sexy and geekish, but more importantly, it is very easy to mistake one for the other. However, if we have a local variable declaration that starts with the final
keyword, then why do we need the var
keyword after that?
Finally, I truly believe that var
is a great tool in Java 11, but I also anticipate that it’s role will be extended in the future.
Thanks for reading!
Published at DZone with permission of Peter Verhas, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments