В Java 10 введен вывод типа локальной переменной с ключевым словом var
. Это означает, что вместо записи:
1
2
3
4
5
6
|
Map<Department, List<Employee>> map = new HashMap<>(); // ... for (Entry<Department, List<Employee>> dept : map.entrySet()) { List<Employee> employees = dept.getValue(); // ... } |
Вы можете использовать var
чтобы уменьшить шаблон, следующим образом:
1
2
3
4
5
6
|
var map = new HashMap<Department, Employee>(); // ... for (var dept : map.entrySet()) { var employees = dept.getValue(); // ... } |
var
устраняет необходимость написания явных типов в вашем коде. Это не только уменьшает количество повторений, но также облегчает поддержку вашего кода, потому что, если, например, вы решите изменить типы объектов, хранящихся на вашей карте в будущем, вам потребуется изменить только одну строку кода.
Полиморфизм:
Теперь давайте посмотрим, как var
ведет себя с полиморфным кодом. Например, если у вас есть класс Shape
с двумя подклассами, Square
и Circle
, какой тип будет выведен, если вы используете var v = new Circle()
? Давайте попробуем это в JShell :
01
02
03
04
05
06
07
08
09
10
11
|
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(); | ^----------^ |
Как показано выше, v
имеет тип Circle
и если вы попытаетесь переназначить его на Square
, компилятор выдаст ошибку.
Анонимные занятия:
Одна из интересных вещей, которую вы можете сделать с помощью var
s, — создавать анонимные классы и обращаться к полям внутри них! Например:
1
2
3
4
5
|
var person = new Object() { String name = "Joe" ; int age = 10 ; }; System.out.println(person.name + ":" + person.age); |
var
определяет тип анонимного класса, что означает, что вы можете использовать анонимный класс в качестве «держателя» для промежуточных значений, не создавая и не поддерживая новый класс. Вот еще один пример, показывающий, как вы можете создавать «временные» объекты человека:
1
2
3
4
5
6
7
|
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)); |
Другие моменты, чтобы отметить:
Вы не можете использовать var
без явной инициализации (присвоение null
не считается) или внутри лямбда-выражений:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
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 = () -> {}; | ^---------------^ |
Опубликовано на Java Code Geeks с разрешения Фахда Шарифа, партнера нашей программы JCG . См. Оригинальную статью здесь: Java 10: ключевое слово «var»
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |