Создавая частный конструктор, мы можем избежать создания экземпляра класса извне. и, делая классным окончанием, ни один другой класс не может его расширить. Почему для класса Util необходимо иметь конструктор private
и класс final
?Обязательный класс утилиты должен быть конечным и частным конструктором?
ответ
Это не мандат с функциональной точки зрения или Java сложности или времени выполнения. Однако его стандарт кодирования принят более широким сообществом. Даже много инструментов для проверки статического кода, таких как checkstyle и многие другие, проверяют, что такие классы имеют это требование.
Зачем следует это соглашение, уже объяснено в других ответах и даже в том, что касается ОП.
Мне нравится объяснять это немного дальше, в основном классы полезности имеют методы/функции, которые не зависят от экземпляра объекта. Это своего рода совокупные функции. Поскольку они зависят только от параметров для возвращаемых значений и не связаны с переменными класса класса utility. Таким образом, в основном эти функции/методы сохраняются статическими. В результате классы Utility - это идеально классы со всеми статическими методами. Итак, любому программисту, вызывающему эти методы, не нужно создавать экземпляр этого класса. Тем не менее, некоторые robo-кодеры (возможно, с меньшим опытом или интересом) будут стремиться создавать объект, как они считают необходимым, до вызова его метода. Чтобы избежать этого создания объекта, у нас есть 3 варианта: -
Keep просвещение люди не создать его экземпляр. (Нет здравомыслящего человека, который может продолжать это делать.)- Отметить класс как аннотация: - Снова теперь robo-кодеры не будут создавать объект. Тем не менее, обзоры и более широкое сообщество java будут утверждать, что абстрактная маркировка означает, что вы хотите, чтобы кто-то ее расширил. Таким образом, это тоже нехороший вариант.
- Частный конструктор: - Защищенный снова позволит дочернему классу создавать объект.
Теперь, если кто-то хочет добавить новый метод для некоторых функций к этому классу служебных программ, ему не нужно его расширять, он может добавить новый метод, поскольку каждый метод является независимым и не может нарушить другие функции , Поэтому нет необходимости переопределять его. А также вы не собираетесь внедрять, поэтому нужно подклассифицировать его. Лучше отметить это окончательно.
Таким образом, создание объекта классов полезности не имеет смысла. Следовательно, конструкторы должны быть либо частными. И вы никогда не хотите переопределять его, поэтому отметьте его окончательным.
Спасибо за пояснение –
Это не обязательно, но это удобно. Класс утилиты является просто владельцем пространства имен связанных функций и не предназначен для создания экземпляров или подкласса. Поэтому предотвращение создания экземпляра и расширения отправляет правильное сообщение пользователю класса.
Поздравляем с 100k :) –
Спасибо, kocko :) –
Значит, это означает, что только для удобства ничего больше? –
По умолчанию этот вид класса обычно используется для агрегатных функций, которые делают разные это, в этом случае нам не нужно, чтобы создать новый объект
Не могли бы вы подробнее рассказать о своем ответе, добавив немного подробного описания вашего решения? – abarisone
Существует важное различие между языком Java и Java Runtime.
Когда класс Java компилируется в байт-код, не существует понятия ограничения доступа, public
, package
, protected
, private
эквивалентны. Всегда можно с помощью отражения или манипуляции байт-кода вызывать конструктор private
, поэтому jvm не может полагаться на эту способность.
final
С другой стороны, это то, что продолжается до байт-кода, а гарантии, которые он предоставляет, могут использоваться javac для генерации более эффективного байт-кода, а jvm - для создания более эффективных машинных инструкций.
Большинство оптимизаций, которые разрешены, больше не актуальны, поскольку jvm теперь применяет те же самые оптимизации для всех классов, которые являются мономорфными во время выполнения, и это всегда было самым важным.
Спасибо за пояснение –
Большинство этих утверждений либо неверны, либо не относятся к классам утилит. 1. 'invokevirtual' не удастся, если ограничение доступа запретит его. 2. Байт-код рефлексивного вызова даже не похож на неотражающий вызов. 3. 'private' влияет на байт-код, _as противоположен' 'final' (' invokespecial' может быть использован). Публичные конечные методы вызываются извне с помощью 'invokevirtual'. 4. 'final' в классе не влияет на вызовы статических методов. –
Как вы думаете, что это обязательно? У вас есть авторитетный источник, который говорит, что это необходимо? – csmckelvey
Подумайте, что вы не можете сделать с классом, который является 'final', и что вы не можете с классом, который имеет конструктор' private'. –
@SubodhJoshi: теперь, своими словами, объясните, что вы думаете, делая классные окончательные изменения. – Stultuske