Java 10 has introduced local variable type inference with the keyword var
. This means that instead of writing:
Map<Department, List<Employee>> map = new HashMap<>(); // ... for (Entry<Department, List<Employee>> dept : map.entrySet()) { List<Employee> employees = dept.getValue(); // ... }
you can use var
to reduce boilerplate, as follows:
var map = new HashMap<Department, Employee>(); // ... for (var dept : map.entrySet()) { var employees = dept.getValue(); // ... }
var
removes the need to have explicit types written in your code. Not only does this reduce repetition but it also makes your code easier to maintain because if, for example, you decide to change the types of the objects stored in your map in the future, you would only need to alter one line of code.
Now let's take a look at how var
behaves with polymorphic code. For example, if you have a class Shape
with two subclasses, Square
and Circle
, what type will be inferred if you use var v = new Circle()
? Let's try it out in JShell:
jshell> var v = new Circle(); v ==> Circle@4e9ba398 jshell> v.getClass(); $13 ==> class Circle jshell> v = new Square(); | Error: | incompatible types: Square cannot be converted to Circle | v = new Square(); | ^----------^
As demonstrated above, v
is of type Circle
and if you try to reassign it to Square
, the compiler will throw an error.
One of the exciting things you can do with var
s is create anonymous classes and refer to fields inside them! For example:
var person = new Object() { String name = "Joe"; int age = 10; }; System.out.println(person.name + ":" + person.age);
var
infers the type of the anonymous class which means that you can use an anonymous class as a "holder" for intermediate values, without having to create and maintain a new class. Here is another example showing how you can create "temporary" person objects:
var persons = Stream.of("Alice", "Bob", "Charles") .map(s -> new Object() { String name = s; int age = 10; }) .collect(toList()); persons.forEach(p -> System.out.println(p.name));Other points to note:
You cannot use var
without an explicit initialisation (assigning to null
does not count) or within lambda expressions:
jshell> var v; | Error: | cannot infer type for local variable v | (cannot use 'var' on variable without initializer) | var v; | ^----^ jshell> var v = null; | Error: | cannot infer type for local variable v | (variable initializer is 'null') | var v = null; | ^-----------^ jshell> var v = () -> {} | Error: | cannot infer type for local variable v | (lambda expression needs an explicit target-type) | var v = () -> {}; | ^---------------^
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.