Возник вопрос по логике кода. Почему компилятор не пропускает такой код?
String testStr;
if (check > 0) {
testStr = "abc";
}
System.out.println(testStr != null ? testStr: "0");
При компиляции выдаётся ошибка:
Error:(134, 32) java: ... variable testStr might not have been initialized
Хотя вроде как логичным будет просто вывести "0" в случае, если testStr не было инициализировано... Какая тут логика?
В Java локальные переменные не имеют значения по умолчанию. Это означает что при простом объявлении переменной у неё не будет значения. В приведённом коде при check<=0 переменная так и останется не инициализированной при обращении к ней, на что и ругается компилятор.
String testStr=null;
Это решит проблему
Есть два варианта интерпретации данного кода:
else. В этом случае компилятор поможет ему найти ошибку.testStr будет инициализировано как null по умолчанию. В этом случае компилятор заставит программиста инициализировать переменную как null явно.Разработчики Java пришли к выводу, что:
Обязательная инициализация локальных переменных определена в спецификации Java:
Chapter 16. Definite Assignment
Each local variable (§14.4) and every blank final field (§4.12.4, §8.3.1.2) must have a definitely assigned value when any access of its value occurs.
An access to its value consists of the simple name of the variable (or, for a field, the simple name of the field qualified by this) occurring anywhere in an expression except as the left-hand operand of the simple assignment operator = (§15.26.1).
For every access of a local variable or blank final field x, x must be definitely assigned before the access, or a compile-time error occurs.
Перевод (из книги «Язык программирования Java SE 8. Подробное описание»)
Глава 16. Определенное присваивание
Каждая локальная переменная (§14.4) и каждое пустое final-поле (§4.12.4, §8.3.1.2) должны иметь определенно присвоенное значение при любом обращении к их значениям.
Обращение к их значениям состоит из простого имени переменной (или, в случае поля, простого имени поля, квалифицированного ключевым словом this), находящегося в любом месте выражения, за исключением левого операнда оператора присваивания = (§15.26.1).
Для каждого обращения к локальной переменной или к пустому final-полю x, x должно быть определенно присвоено до этого обращения, иначе генерируется ошибка времени компиляции.
Посмотрите также обсуждения этого вопроса в английской версии:
Продвижение своими сайтами как стратегия роста и независимости