Страницы

Поиск по вопросам

вторник, 9 октября 2018 г.

Ошибка “variable might not have been initialized”

Возник вопрос по логике кода. Почему компилятор не пропускает такой код?
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 не было инициализировано... Какая тут логика?


Ответ

Есть два варианта интерпретации данного кода:
Программист хотел объявить переменную с каким-то значением, но допустил ошибку в коде: пропустил присвоение значения либо блок 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 должно быть определенно присвоено до этого обращения, иначе генерируется ошибка времени компиляции.
Посмотрите также обсуждения этого вопроса в английской версии:
Why are local variables not initialized in Java? Why must local variables, including primitives, always be initialized in Java?

Комментариев нет:

Отправить комментарий