2015-09-03 4 views
5

Создавая частный конструктор, мы можем избежать создания экземпляра класса извне. и, делая классным окончанием, ни один другой класс не может его расширить. Почему для класса Util необходимо иметь конструктор private и класс final?Обязательный класс утилиты должен быть конечным и частным конструктором?

+1

Как вы думаете, что это обязательно? У вас есть авторитетный источник, который говорит, что это необходимо? – csmckelvey

+0

Подумайте, что вы не можете сделать с классом, который является 'final', и что вы не можете с классом, который имеет конструктор' private'. –

+0

@SubodhJoshi: теперь, своими словами, объясните, что вы думаете, делая классные окончательные изменения. – Stultuske

ответ

4

Это не мандат с функциональной точки зрения или Java сложности или времени выполнения. Однако его стандарт кодирования принят более широким сообществом. Даже много инструментов для проверки статического кода, таких как checkstyle и многие другие, проверяют, что такие классы имеют это требование.

Зачем следует это соглашение, уже объяснено в других ответах и ​​даже в том, что касается ОП.

Мне нравится объяснять это немного дальше, в основном классы полезности имеют методы/функции, которые не зависят от экземпляра объекта. Это своего рода совокупные функции. Поскольку они зависят только от параметров для возвращаемых значений и не связаны с переменными класса класса utility. Таким образом, в основном эти функции/методы сохраняются статическими. В результате классы Utility - это идеально классы со всеми статическими методами. Итак, любому программисту, вызывающему эти методы, не нужно создавать экземпляр этого класса. Тем не менее, некоторые robo-кодеры (возможно, с меньшим опытом или интересом) будут стремиться создавать объект, как они считают необходимым, до вызова его метода. Чтобы избежать этого создания объекта, у нас есть 3 варианта: -

  1. Keep просвещение люди не создать его экземпляр. (Нет здравомыслящего человека, который может продолжать это делать.)
  2. Отметить класс как аннотация: - Снова теперь robo-кодеры не будут создавать объект. Тем не менее, обзоры и более широкое сообщество java будут утверждать, что абстрактная маркировка означает, что вы хотите, чтобы кто-то ее расширил. Таким образом, это тоже нехороший вариант.
  3. Частный конструктор: - Защищенный снова позволит дочернему классу создавать объект.

Теперь, если кто-то хочет добавить новый метод для некоторых функций к этому классу служебных программ, ему не нужно его расширять, он может добавить новый метод, поскольку каждый метод является независимым и не может нарушить другие функции , Поэтому нет необходимости переопределять его. А также вы не собираетесь внедрять, поэтому нужно подклассифицировать его. Лучше отметить это окончательно.

Таким образом, создание объекта классов полезности не имеет смысла. Следовательно, конструкторы должны быть либо частными. И вы никогда не хотите переопределять его, поэтому отметьте его окончательным.

+1

Спасибо за пояснение –

5

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

+2

Поздравляем с 100k :) –

+0

Спасибо, kocko :) –

+0

Значит, это означает, что только для удобства ничего больше? –

-1

По умолчанию этот вид класса обычно используется для агрегатных функций, которые делают разные это, в этом случае нам не нужно, чтобы создать новый объект

+1

Не могли бы вы подробнее рассказать о своем ответе, добавив немного подробного описания вашего решения? – abarisone

0

Существует важное различие между языком Java и Java Runtime.

Когда класс Java компилируется в байт-код, не существует понятия ограничения доступа, public, package, protected, private эквивалентны. Всегда можно с помощью отражения или манипуляции байт-кода вызывать конструктор private, поэтому jvm не может полагаться на эту способность.

final С другой стороны, это то, что продолжается до байт-кода, а гарантии, которые он предоставляет, могут использоваться javac для генерации более эффективного байт-кода, а jvm - для создания более эффективных машинных инструкций.

Большинство оптимизаций, которые разрешены, больше не актуальны, поскольку jvm теперь применяет те же самые оптимизации для всех классов, которые являются мономорфными во время выполнения, и это всегда было самым важным.

+0

Спасибо за пояснение –

+1

Большинство этих утверждений либо неверны, либо не относятся к классам утилит. 1. 'invokevirtual' не удастся, если ограничение доступа запретит его. 2. Байт-код рефлексивного вызова даже не похож на неотражающий вызов. 3. 'private' влияет на байт-код, _as противоположен' 'final' (' invokespecial' может быть использован). Публичные конечные методы вызываются извне с помощью 'invokevirtual'. 4. 'final' в классе не влияет на вызовы статических методов. –