Ответ 1
Отвечая на каждую из ваших точек по очереди:
примитивные переменные: могут быть установлены только один раз. (память и коэффициент усиления)
Да, но нет усиления памяти и нет увеличения производительности. (Предполагаемый прирост производительности зависит от настройки только один раз... не от final
.)
переменные объектов: могут быть изменены, final применяется к объектной ссылке.
Да. (Однако это описание не соответствует тому, что это полностью согласуется с тем, как остальная часть языка Java имеет дело с двойственностью объекта/ссылки. Например, когда объекты передаются как параметры и возвращаются как результаты.)
: можно установить только один раз.
Реальный ответ: тот же, что и для переменных.
методы: не могут быть переопределены, скрыты.
Да. Но также обратите внимание, что здесь происходит то, что ключевое слово final
используется в другом синтаксическом контексте, чтобы означать нечто отличное от final
для поля/переменной.
классы: не могут быть расширены.
Да. Но также см. Примечание выше.
сбор мусора: заставит Java-генерацию мусора собирать метку для двойной развертки.
Это вздор. Ключевое слово final
не имеет никакого отношения к сборке мусора. Возможно, вы сбиваете с толку final
с завершением... они не связаны.
Но даже финализаторы не форсируют лишнюю развертку. Что происходит, так это то, что объект, который нуждается в завершении, устанавливается с одной стороны, пока основной GC не закончится. Затем GC запускает метод finalize для объекта и устанавливает его флаг... и продолжает. В следующий раз, когда GC запускается, объект рассматривается как обычный объект:
- если он доступен, он помечен и скопирован
- если он недоступен, он не помечен.
(Ваша характеристика - "Явная генерация мусора для генерации мусора Java" искажена. Сборщик мусора может быть либо "mark-sweep", либо "generational" (подкласс "копирование" ). Это не может быть и то, и другое. Java обычно использует коллекцию поколений и только возвращается к разметке в чрезвычайных ситуациях, т.е. При нехватке места или когда сборщик с низкой паузой не может идти в ногу.)
Может сделать клон неудачным (это хорошо и плохо)
Я так не думаю.
Может создавать неизменяемые примитивы aka const
Да.
Может сделать пустой неизменный - инициализирован при создании aka readonly
Да... хотя я никогда не слышал ранее употребляемого слова "пустой неизменный".
Может сделать объекты неперемещаемыми
Изменчивость объекта связана с изменением наблюдаемого состояния. Таким образом, объявление атрибутов final
может или не может заставить объект вести себя как неизменяемый. Кроме того, понятие "неглубоко неизменное" не определено четко, не в последнюю очередь потому, что понятие "мелкого" не может быть отображено без глубокого знания семантики класса.
(Чтобы быть ясным, изменчивость переменных/полей является четко определенной концепцией в контексте JLS. Это просто концепция изменчивости объектов undefined с точки зрения JLS.)
Может сделать видимость видимости/видимость неизменной
Терминологическая ошибка. Мутируемость - это состояние объекта. Видимость и область видимости отсутствуют.
Может сделать служебную нагрузку вызова метода меньшей (потому что ей не нужна виртуальная таблица)
На практике это не имеет значения. Современный JIT-компилятор также делает эту оптимизацию для не конечных методов, если они не переопределены каким-либо классом, который фактически использует приложение. (Умное вещество случается...)
Можно использовать аргументы метода как окончательные (даже если у вас нет)
А? Я не могу разобрать это предложение.
Может создавать объекты threadafe
В определенных ситуациях да.
(если объект определен как final, он не будет окончательным аргументом метода)
Да, если вы имеете в виду, если класс является окончательным. Объекты не являются окончательными.
Можете сделать макетные тесты (не то, чтобы вы могли что-то с этим сделать), вы можете сказать, что предполагаются ошибки)
Не разбирается.
Невозможно подружиться (переменимо с другими друзьями и неизменным для отдыха)
В Java нет "друзей".
Невозможно сделать mutable, который будет изменен, чтобы быть неизменным позже (но может с шаблоном factory как исправление)
Да для первого поля final
нельзя переключить с измененного на неизменяемое.
Неясно, что вы подразумеваете под второй частью. Верно, что вы можете использовать шаблон factory (или построитель) для создания неизменяемых объектов. Однако, если вы используете final
для полей объекта ни в какой точке, объект будет изменяться.
В качестве альтернативы вы можете реализовать неизменяемые объекты, которые используют нефинализированные поля для представления неизменяемого состояния, и вы можете разработать API, чтобы вы могли "перевернуть переключатель", чтобы сделать ранее измененный объект неизменным с этого момента. Но если вы примете такой подход, вам нужно быть более осторожным с синхронизацией... если ваши объекты должны быть потокобезопасными.
Невозможно сделать элементы массива неизменными, ака глубоко неизменными
Да, но ваша терминология нарушена; см. комментарий выше о "мелкой изменчивости".
Невозможно создать новые экземпляры объекта (это хорошо и плохо)
Нет. Там ничего не мешает вам создать новый экземпляр объекта с конечными полями или окончательный класс или окончательные методы.
Невозможно выполнить сериализацию
Нет. Сериализация работает. (Конечно, десериализация полей final
с использованием пользовательского метода readObject
представляет проблемы... хотя вы можете обойти их с помощью рефлексивных хаков.)
Нет альтернатив окончательному,
Правильно.
но существует оболочка + private
Да, по модулю, что (строго говоря) несинхронизированный геттер для не конечного поля может быть небезопасным... даже если он инициализируется при построении объекта и никогда не менялся!
и перечисления.
Решает другую проблему. И enums
может быть изменен.