Java Local Variable Type Inference examples
In this post:
- what is Local Variable Type Inference
- examples
- when is useful
- what is not allowed
Short video tutorial: java local variable type inference examples
Java 10 and Local Variable Type Inference
Since Java 10 new feature is added - Local Variable Type Inference - or shortly as code examples:
Integer Example
var x = 5 //inferred to be type int
checking the type by:
System.out.println(((Object)x).getClass().getName());
result:
java.lang.Integer
this is the wrapper Integer of the primitive int
String Example:
jshell> var y = "f";
y ==> "f"
checking the type by:
jshell> y.getClass().getName()
$5 ==> "java.lang.String"
result:
java.lang.String
Collection Example:
This is very useful for shortening and making Java more concise about the syntactic burden that is part of Java since it's early versions. Of course some people may be concerned about how accurate the infer is working. In the example below we see collections:
var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>
Can you change the type
Yes you can change the type of local variable with type inference but this could be misleading and maybe a bad practice:
jshell> var n = 0
n ==> 0
jshell> var n = "a"
n ==> "a"
jshell> var n = 1.0
n ==> 1.0
Have in mind that this can be removed from future versions of Java.
What is var?
Var is reserved type name ( and not a keyword as many could think of). You can consider var as a special type.
What else is new in java 10:
How to install Java 10 and what's new
Examples
For loop
The first example to come to mind is loop for:
for (var x=0; x<6; x++) { System.out.print(x); }
result:
012345
or for other numeric formats:
for (var x=0.0; x<10.0; x+=0.5) { System.out.print(x + "; "); }
result:
0.0; 0.5; 1.0; 1.5; 2.0; 2.5; 3.0; 3.5; 4.0; 4.5; 5.0; 5.5; 6.0; 6.5; 7.0; 7.5; 8.0; 8.5; 9.0; 9.5;
Collections
Initialization of collections now it's easier and shorter:
Map<String,Integer> mixedMap = new HashMap <> ();
Map<String,String> stringMap = new HashMap <> ();
Map<String,String> intMap = new HashMap <> ();
var mapInfer = new HashMap <String,String> ();
var mapSimple = new HashMap <> ();
Let's add some values to mapSimple and print the result:
mapSimple.put("a","b")
mapSimple.put(1,1)
mapSimple.forEach((key, value) -> System.out.printf("%s %s%n", key, value));
result:
a b
1 1
More about maps: Java map examples
We can do also:
var a = 1;
var b = "h";
mapSimple.forEach((key, value) -> System.out.printf("%s %s%n", key, value));
result:
1 h
Note: that even a is from type int finally is converted to String.
Local Variable Type Inference what is not allowed
No multiple variables yet
var a=1,b=0;
this gives an error:
Error:
'var' is not allowed in a compound declaration
var a=1,b=0;
Assign null
In Java you can declare and initialize variable as:
jshell> String x = null
x ==> null
but you can't use it with type inference:
jshell> var x = null
| Error:
| cannot infer type for local variable x
| (variable initializer is 'null')
| var x = null;
| ^-----------^
Declaration only
In order to use inference of local variables you should also initialize them:
jshell> var x;
| Error:
| cannot infer type for local variable x
| (cannot use 'var' on variable without initializer)
| var x;
| ^----^
No Array Initializers, Lambdas, Method References, no method return type or parameters
- No Array Initializers
For example you can initialize array in Java with:
int[] data = {10,20,30,40,50,60,71,80,90,91};
but if you try this with local variable inference you will get an error:
jshell> var data = {10,20,30,40,50,60,71,80,90,91};
| Error:
| cannot infer type for local variable data
| (array initializer needs an explicit target-type)
| var data = {10,20,30,40,50,60,71,80,90,91};
- No lambdas with type inference:
You can't use:
var runner = () -> { System.out.println("Hello World!"); };
You should always use:
Runnable runner = () -> { System.out.println("Hello World!"); };
Otherwise error is raised:
| cannot infer type for local variable runner
| (lambda expression needs an explicit target-type)
- No method References
You can't use:
var show = MethodReference::showAge;
Because of error:
| cannot infer type for local variable show
| (method reference needs an explicit target-type)
You need to use:
Consumer<Integer> show = MethodReference::showAge;
full example
public class MethodReference {
public static void main(String[] args) {
Consumer<Integer> show = MethodReference::showAge;
}
public static void showAge(Integer x) {
System.out.println(x);
}
}
- no type inference for method parameters or return types:
public var readMe(var str1, var str2) {
return str1 + str2;
}
Or you will get compilation error:
| 'var' is not allowed here
| public var readMe(var str1, var str2) {
| -
You need to provide them explicitly:
public String readMe(String str1, String str2) {
return str1 + str2;
}