Перейти к основному содержимому

Вывод типа LocalVariable в Java 10

· 4 мин. чтения

1. Обзор

Одним из наиболее заметных улучшений в JDK 10 является определение типа локальных переменных с помощью инициализаторов.

В этом руководстве подробно рассказывается об этой функции с примерами.

2. Введение

До Java 9 нам приходилось явно указывать тип локальной переменной и обеспечивать ее совместимость с инициализатором, используемым для ее инициализации:

String message = "Good bye, Java 9";

В Java 10 мы могли бы объявить локальную переменную следующим образом:

@Test
public void whenVarInitWithString_thenGetStringTypeVar() {
var message = "Hello, Java 10";
assertTrue(message instanceof String);
}

Мы не предоставляем тип данных сообщения . Вместо этого мы помечаем сообщение как переменную , и компилятор делает вывод о типе сообщения из типа инициализатора, представленного в правой части.

В приведенном выше примере тип сообщения будет String .

Обратите внимание, что эта функция доступна только для локальных переменных с инициализатором. Его нельзя использовать для переменных-членов, параметров метода, возвращаемых типов и т. д. — требуется инициализатор, без которого компилятор не сможет определить тип.

Это усовершенствование помогает сократить шаблонный код; Например:

Map<Integer, String> map = new HashMap<>();

Теперь это можно переписать как:

var idToNameMap = new HashMap<Integer, String>();

Это также помогает сосредоточиться на имени переменной, а не на ее типе.

Следует также отметить, что var не является ключевым словом — это обеспечивает обратную совместимость для программ, использующих var , скажем, в качестве имени функции или переменной. var — зарезервированное имя типа, как и int .

Наконец, обратите внимание, что при использовании var нет накладных расходов во время выполнения и это не делает Java языком с динамической типизацией. `` Тип переменной выводится во время компиляции и не может быть изменен позже.

3. Незаконное использование var

Как упоминалось ранее, var не будет работать без инициализатора:

var n; // error: cannot use 'var' on variable without initializer

Это также не сработает, если оно инициализировано с помощью null :

var emptyList = null; // error: variable initializer is 'null'

Это не будет работать для нелокальных переменных:

public var = "hello"; // error: 'var' is not allowed here

Для лямбда-выражения требуется явный целевой тип, поэтому var нельзя использовать:

var p = (String s) -> s.length() > 10; // error: lambda expression needs an explicit target-type

То же самое и с инициализатором массива:

var arr = { 1, 2, 3 }; // error: array initializer needs an explicit target-type

4. Рекомендации по использованию var

Бывают ситуации, когда var можно использовать на законных основаниях, но это может быть не очень хорошей идеей.

Например, в ситуациях, когда код может стать менее читаемым:

var result = obj.prcoess();

Здесь, несмотря на легальное использование var , становится трудно понять тип, возвращаемый process() , что делает код менее читаемым.

На java.net есть специальная статья «Рекомендации по стилю для определения типа локальной переменной в Java» , в которой рассказывается о том, как мы должны использовать суждение при использовании этой функции.

Другая ситуация, когда лучше избегать var , — это потоки с длинным конвейером:

var x = emp.getProjects.stream()
.findFirst()
.map(String::length)
.orElse(0);

Использование var также может дать неожиданный результат.

Например, если мы используем его с оператором алмаза, представленным в Java 7:

var empList = new ArrayList<>();

Тип empList будет ArrayList<Object> а не List<Object> . Если мы хотим, чтобы это был ArrayList<Employee> , мы должны быть явными:

var empList = new ArrayList<Employee>();

Использование var с неопределяемыми типами может привести к непредвиденной ошибке.

Например, если мы используем var с экземпляром анонимного класса:

@Test
public void whenVarInitWithAnonymous_thenGetAnonymousType() {
var obj = new Object() {};
assertFalse(obj.getClass().equals(Object.class));
}

Теперь, если мы попытаемся присвоить obj другой объект , мы получим ошибку компиляции: ``

obj = new Object(); // error: Object cannot be converted to <anonymous Object>

Это связано с тем, что предполагаемый тип obj не является Object .

5. Вывод

В этой статье мы увидели новую функцию вывода типа локальной переменной Java 10 с примерами.

Как обычно, фрагменты кода можно найти на GitHub .