Объявление локальных переменных как финальных без инициализатора и присваивание в операторе if - PullRequest
14 голосов
/ 18 января 2012

Я только что сделал небольшое изменение кода, чтобы заставить замолчать предупреждение FindBugs, которое требовало перемещения некоторого кода в анонимный внутренний класс.Чтобы получить доступ к некоторым переменным, я должен был объявить их как final.Итак, это фрагмент кода после изменения:

final File[] libPath; // libPath is final but assignment takes place later
if (libraryPath != null) {
    libPath = pathToFiles(libraryPath);
} else {
    libPath = new File[0];
}

Это прекрасно компилируется с языком, установленным на Java 6 в текущем Eclipse (Версия 3.7.1).Однако я вполне уверен, что это использовалось, чтобы выдать ошибку в какой-то предыдущей версии.Кажется, компилятор принимает эту конструкцию, когда он может определить, что будет.

Мой вопрос: это законно в Java 6 или это то, что сейчас работает из-за побочного эффекта поддержки Java 7, добавленного в eclipse 3.7.1?Мы видели такие побочные эффекты при определенном использовании обобщений, которые работают в 3.7.1, но не компилируются в 3.7.0.

Ответы [ 6 ]

14 голосов
/ 18 января 2012

это нормально.она называется blank final

цитата из вики:

Окончательная переменная может быть инициализирована только один раз, либо через инициализатор, либо через оператор присваивания.Его не нужно инициализировать в точке объявления: это называется «пустой конечной» переменной.Пустая конечная переменная экземпляра класса должна быть обязательно назначена в конце каждого конструктора класса, в котором она объявлена;аналогично, пустая конечная статическая переменная должна быть определенно назначена в статическом инициализаторе класса, в котором она объявлена: в противном случае ошибка времени компиляции происходит в обоих случаях.[4] (Примечание: если переменная является ссылкой, это означает, что переменная не может быть повторно связана с ссылкой на другой объект. Но объект, на который она ссылается, остается изменяемым, если он изначально был изменяемым.)

Пустой финал

Пустой финал, который был представлен в Java 1.1, является конечной переменной, в объявлении которой отсутствует инициализатор.[5] [6] Пустой финал может быть назначен только один раз и должен быть отменен при назначении.Для этого компилятор Java запускает анализ потока, чтобы убедиться, что для каждого присваивания пустой конечной переменной переменная определенно не присваивается перед присваиванием;в противном случае возникает ошибка времени компиляции. [7]

Как правило, компилятор Java гарантирует, что пустой финал не будет использован, пока ему не будет присвоено значение, и если однажды присвоено значение, то теперь последняя переменная не можетпереназначить другое значение. [8]

ссылка: http://en.wikipedia.org/wiki/Final_%28Java%29

8 голосов
/ 18 января 2012

Это было разрешено и работало нормально начиная с Java 1.1 и не доставит вам проблем с другими компиляторами или IDE.

Это стандартное поведение в Java, которое впервые было формально указано в Спецификации языка Java2-е издание .

1 голос
/ 18 января 2012

Спецификация языка Java содержит целую главу, посвященную этому поведению ( Глава 16 Определенное назначение ).

Это поведение полностью определено, так что я думаю, что вы что-то неверно истолковали, когда говорите, чтоиспользуется для создания ошибки в предыдущих версиях.

0 голосов
/ 18 января 2012

Да, это будет работать и безопасно для использования во всех версиях Java, которые я видел (1.3 +).

final означает, что вы не можете изменить значение объекта после того, как он был инициализирован, если вы поместили в объявление пустое значение, он бы сломался.

0 голосов
/ 18 января 2012

Я настоятельно рекомендую использовать вместо этого код:

final File[] libPath = ibraryPath == null ? new File[0] : pathToFiles(libraryPath);

Это не зависит от какой-либо версии компилятора, но на 100% поддерживается Java с ясным значением.

0 голосов
/ 18 января 2012

Всё хорошо.Переменная не имеет значения и назначается только один раз.Он потерпит неудачу, если вы изначально зададите ему значение null

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...