Статьи

Java 10: ключевое слово «var»

В 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, являются их собственными.