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

Плюсы и минусы пакетов частных классов в Java?

Я изучаю Java недавно, и я натолкнулся на понятие классов package-private, которое является значением по умолчанию, если мы ничего не укажем. Но потом я понял:

  • Я редко вижу использование пакета-частного класса. Есть ли причина для этого, например, имеет серьезные недостатки, она избыточна или просто я недостаточно читаю? Существуют ли сильные аргументы в отношении/против его использования?

  • Если это действительно не полезно в большинстве случаев, почему это будет по умолчанию?

  • В какой ситуации мы должны использовать пакет-частный в реальном мире? I.e., когда он станет незаменимым?

Другими словами, каковы основные плюсы и минусы модификатора пакета-частного по умолчанию?

4b9b3361

Ответ 1

Короткий ответ - это несколько более широкая форма частного.

Я предполагаю, что вы знакомы с различием между public и private и почему в целом хорошая практика заключается в создании методов и переменных private, если они будут использоваться исключительно внутри класс, о котором идет речь.

Ну, в качестве дополнения к этому - если вы подумываете о создании своего программного обеспечения модульным способом, вы можете подумать о публичном интерфейсе к вашему модулю, который будет иметь внутри него несколько классов, которые будут сотрудничать между собой. В этом контексте имеет смысл делать методы public, если они будут вызваны потребителями; private, если они являются внутренними для класса; и package private, если они используются для вызова между классами в этом модуле, т.е. это деталь реализации вашего модуля (как видно публичным абонентам), но охватывает несколько классов.

Это редко используется на практике, потому что пакетная система оказывается не такой полезной для такого рода вещей. Вам придется сбрасывать все классы для данного модуля в один и тот же пакет, который для чего-то нетривиального будет немного громоздким. Итак, идея велика - сделать метод доступным только для нескольких "близлежащих" классов, как немного более широкий private, но ограничения на то, как вы определяете этот набор классов, означает, что он редко используется/полезен.

Ответ 2

Одна приятная вещь о пакете-private заключается в том, что вы можете использовать его для предоставления доступа к методам, которые в противном случае считались бы частными для классов unit test. Недостатком, конечно же, является то, что другие классы в пакете могли бы назвать это, когда они действительно не должны.

Ответ 3

Относительно вопроса о том, "почему это было бы по умолчанию", в этом контексте термин "дефолт" означает только отсутствие другого классификатора. Я думаю, они могли бы придумать другое ключевое слово ( "пакет" уже был занят), но они этого не сделали.

В реальном мире я использую доступ по умолчанию для классов полезности и абстрактных классов, которые я не хочу, чтобы люди вызывали или иным образом использовали их из других пакетов. Скажем, у вас есть интерфейс и две конкретные реализации, которые простираются от некоторого абстрактного класса. Вы объявляете свои два конкретных класса окончательными, потому что вы не обязательно хотите, чтобы люди подклассифицировали их (см. "Эффективная Java" ). Вы также не хотите, чтобы люди обезьяны с вашим абстрактным классом по той же причине. Если вы используете доступ по умолчанию для абстрактного класса, тогда люди видят его только в том случае, если они помещают свой класс в ваш пакет. Это не доказательство пули, но я считаю это разумным использованием/иллюстрацией доступа по умолчанию. Тем не менее, тот факт, что он не мешает детализации утечки как конфиденциальной, т.е. Ничего не гарантирует, означает, что это не особенно полезное соглашение.

Еще одна причина, по которой вы не видели ее чаще, заключается в том, что люди склонны исключать классы с доступом по умолчанию из своих javadocs.

Ответ 4

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

В качестве примера вы можете взглянуть на библиотеку, которую я разработал. javadoc содержит только 5 интерфейсов и 12 классов, хотя исходный код имеет намного больше. Но то, что скрыто, - это в основном внутренние слои, которые не обеспечивают добавленную стоимость для клиента (как правило, все абстрактные базовые классы скрыты).

В JDK также много примеров.

Ответ 5

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

2 - По умолчанию (I.e. public/protected/private) не то же самое, что и личное - это 4-е состояние. См. Контроль доступа Java

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

Ответ 6

Обратите внимание, что когда вы говорите о занятиях, у вас есть только два варианта:

  • публичные классы
  • частные классы

Понятие "частный класс" не имеет смысла. (Зачем делать класс, который нигде не используется?!)

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

Также, когда вы определяете многие классы в одном исходном файле, разрешается публиковать только один класс (его имя совпадает с именем .java файла). Если какой-либо другой класс определен в том же файле, он должен быть "приватным пакетом".

Ответ 7

Уровень доступа к частному доступу более ограничительный, чем protected: защищенные атрибуты и методы все еще доступны, просто подклассифицируя класс. Защищенные члены являются (или могут быть) предназначены для наследования, в то время как члены с закрытым пакетом не являются.

Частые члены пакета часто используются, поэтому классы multilpe внутри пакета могут обращаться к атрибутам, специфичным для реализации, или (служебным) методам.

Хорошими примерами этого являются конструктор private-package String и массив StringBuilder.value char:

/*
* Package private constructor which shares value array for speed.
* this constructor is always expected to be called with share==true.
* a separate constructor is needed because we already have a public
* String(char[]) constructor that makes a copy of the given char[].
*/
String(char[] value, boolean share) {
    // assert share : "unshared not supported";
    this.value = value;
}

Таким образом, классы внутри пакета java.lang могут эффективно создавать новый Strings, если контент уже присутствует в char[] без ущерба для безопасности. Вы не можете сделать это из своего приложения, потому что, если бы вы могли, у вас был бы доступ (ссылка) к внутреннему массиву char String, который является неизменным (отражение не учитывается!).

В StringBuilder (или, скорее, AbstractStringBuilder, где реализована реализация) массив char, содержащий текущее значение char[] value, а метод доступа к этому char[] getValue() также является пакетным, поэтому различные полезные методы String как contentEquals(StringBuffer sb) и contentEquals(CharSequence cs) могут использовать это для эффективности и более быстрого сравнения, не подвергая внутренний массив char "миру".

Ответ 8

"Частный пакет" используется, когда у вас несколько пакетов, а это значит, что другие классы в одном пакете могут получить доступ к этому классу или члену класса как "общедоступный", классы в других пакетах не могут получить доступ, например "частные". "