Страницы

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

воскресенье, 1 декабря 2019 г.

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

#java #компиляция


Возник вопрос по логике кода. Почему компилятор не пропускает такой код?

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 не было инициализировано...
Какая тут логика?
    


Ответы

Ответ 1



Есть два варианта интерпретации данного кода: Программист хотел объявить переменную с каким-то значением, но допустил ошибку в коде: пропустил присвоение значения либо блок 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?

Ответ 2



В Java локальные переменные не имеют значения по умолчанию. Это означает что при простом объявлении переменной у неё не будет значения. В приведённом коде при check<=0 переменная так и останется не инициализированной при обращении к ней, на что и ругается компилятор. String testStr=null; Это решит проблему

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

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