Вывод типа локальной переменной 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.