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



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




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


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


  3. в какой ситуации мы должны использовать package-private в реальном мире? То есть, когда он станет незаменимым?



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

616   8  

8 ответов:

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

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

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

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

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

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

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

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

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

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

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

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

2-по умолчанию (т. е. не public/protected/private) это не то же самое, что private - это 4-е состояние. Смотрите Java Access Control

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

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

пакет-частные члены часто используются так многослойные классы внутри пакета могут получить доступ реализации атрибуты или (утилиты) методы.

хорошие примеры это пакет-частный конструктор 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[] без ущерба для безопасности. Вы не можете сделать это из своего приложения, потому что если бы вы могли, у вас был бы доступ (ссылка) к внутреннему массиву символов a String который является неизменным (отражение не считается!).

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

Пожалуйста, обратите внимание, что когда вы говорите о классах, у вас есть только два варианта:

  1. общественные классы
  2. пакет частных классов

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

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

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

" Package Private "используется, когда у вас есть несколько пакетов, и это означает, что другие классы в том же пакете могут получить доступ к этому классу или члену класса как" public", классы в других пакетах не могут получить доступ, его как " private like them."

Comments

    Ничего не найдено.