Java 10 LocalVariable Type-Inference

Вывод типа локальной переменной Java 10

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);
}

Мы не предоставляем тип данныхmessage. Вместо этого мы помечаемthe message  какvar, и компилятор выводит типmessage  из типа инициализатора, представленного справа.

В приведенном выше примере типmessage должен бытьString.

Note that this feature is available only for local variables with the initializer.  Его нельзя использовать для переменных-членов, параметров метода, возвращаемых типов и т. д. - требуется инициализатор, поскольку без него компилятор не сможет определить тип.

Это улучшение помогает в сокращении стандартного кода; например:

Map map = new HashMap<>();

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

var idToNameMap = new HashMap();

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

Также следует отметить, чтоvar is not a keyword - это обеспечивает обратную совместимость для программ, использующихvar say в качестве имени функции или переменной. var - зарезервированное имя типа, как иint.

Наконец, обратите внимание, что существуетno runtime overhead in using var nor does it make Java a dynamically typed language.  Тип переменной все еще определяется во время компиляции и не может быть изменен позже.

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

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

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 can может использоваться легально, но это может быть не очень хорошей идеей.

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

var result = obj.prcoess();

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

java.net- это специальная статья оStyle Guidelines for Local Variable Type Inference in Java w, в которой рассказывается о том, как мы должны использовать суждения при использовании этой функции.

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

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

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

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

var empList = new ArrayList<>();

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

var empList = new ArrayList();

Использованиеvar w с необозначимыми типами может вызвать непредвиденную ошибку.

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

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

Теперь, если мы попытаемся назначить другойObjecttoobj, мы получим ошибку компиляции:

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

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

5. Заключение

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

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