Locale variable type inference in Java
Java 10, which was released in March 2018, introduced the var
keyword. The official name of this new feature is locale variable type inference. So it's about a variable:
String name = "Tonny";
Not any variable, but local variable:
public void aMethod() {
String name = "Tonny";
}
Basically, we're saying that it's fun to say name
is a String
, but the compiler should know the type by itself. Thus, we can replace the type, String
in this example, with var
:
public void aMethod() {
var name = "Tonny";
}
Is Java now JavaScript? Is it now a dynamic language? No, it definetly isn't. It's still staticly defined, but by the compiler.
Improve readability
Should you now change all types of local variables to var
? No, please don't.
You should only use var
if you think that it will improve the readability of your code. For example, if we have the following code:
URL url = new URL("https://tonnygaric.com");
URLConnection connection = url.openConnection();
BufferedInputStream inputStream = new BufferedInputStream(connection.getInputStream());
We can improve the readability by using var
, because the types of the variables are redundant—the names of the variables are self explanatory:
var blogUrl = new URL("https://tonnygaric.com");
var connection = blogUrl.openConnection();
var blogStream = new BufferedInputStream(connection.getInputStream());
Types
By now you know that if you use var
, the compiler will define the type of the variable. The compiler will try to be as precise as possible.
We can use jshell to see what types the compiler picks. Note that you must be running JDK 10 or later. We can open jshell with verbose feedback:
jshell -feedback verbose
Or open jshell and set the feedback afterwards on verbose mode:
/set feedback verbose
We can now test what types the compiler would pick, by assigning a value to a variable with the var
keyword:
jshell> var i = 1
i == > 1
| created variable i : int
jshell> var j = 2.0
i ==> 2.0
| created variable j : double
If we use the new collection factory method List.of()
, we can see how the compiler can pick the most precise type:
jshell> var list = List.of(1, 2.0d, "three")
list ==> [1, 2.0, three]
| created variable list : List<Serializable&Comparable<? extends Serializable&Comparable<?>>>
As you can see, a compiler knows how to find more specific and precise types than we -developers- can do.
null
Assiging null
to a variable with keyword var
is not allowed:
jshell> var k = null
| Error:
| cannot infer type for local variable k
| (variable initializer is 'null')
| var k = null;
| ^-----------^
If you specify more information, for example an explicit cast, it is allowed:
jshell> var k = (Object) null
k ==> null
| created variable k : Object