Подтвердить что ты не робот

Объявление локальных переменных как final без инициализатора и назначение в if-statement

Я просто сделал небольшое изменение кода, чтобы отключить предупреждение 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.

4b9b3361

Ответ 1

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

Это стандартное поведение в Java и впервые было официально определено в Спецификация Java Language Specification 2nd Edition.

Ответ 2

Это нормально. он называется пустой конечной

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

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

Пустое окончательное

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

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

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

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