У меня есть два пакета в моем проекте: odp.proj
и odp.proj.test
. Есть определенные методы, которые я хочу видеть только для классов в этих двух пакетах. Как я могу это сделать?
РЕДАКТИРОВАТЬ: Если в Java нет концепции подпакета, есть ли способ обойти это? У меня есть определенные методы, которые я хочу использовать только для тестировщиков и других участников этого пакета. Должен ли я просто выбросить все в одну и ту же упаковку? Использовать обширные размышления?
java
package
visibility
encapsulation
Ник Хейнер
источник
источник
Ответы:
Ты не можешь В Java нет понятия подпакета, а значит
odp.proj
иodp.proj.test
являются совершенно отдельными пакетами.источник
Названия ваших пакетов намекают на то, что приложение здесь для модульного тестирования. Типичный используемый шаблон - поместить классы, которые вы хотите протестировать, и код модульного теста в один и тот же пакет (в вашем случае
odp.proj
), но в разные исходные деревья. Таким образом, вы вставили бы свои классыsrc/odp/proj
и свой тестовый кодtest/odp/proj
.В Java есть модификатор доступа «пакет», который является модификатором доступа по умолчанию, когда ничего не указано (т. Е. Вы не указываете открытый, закрытый или защищенный). С модификатором доступа «package»
odp.proj
доступ к методам имеют только классы . Но имейте в виду, что в Java нельзя полагаться на модификаторы доступа для обеспечения соблюдения правил доступа, поскольку с отражением возможен любой доступ. Модификаторы доступа являются просто наводящими (если не присутствует ограничительный менеджер безопасности).источник
Это не особая связь между
odp.proj
иodp.proj.test
- их просто называют явно связанными.Если пакет odp.proj.test просто предоставляет тесты, вы можете использовать то же имя пакета (
odp.proj
). Среды IDE, такие как Eclipse и Netbeans, будут создавать отдельные папки (src/main/java/odp/proj
иsrc/test/java/odp/proj
) с тем же именем пакета, но с семантикой JUnit.Обратите внимание, что эти IDE будут генерировать тесты для методов
odp.proj
и создавать соответствующую папку для методов тестирования, которых не существует.источник
Когда я делаю это в IntelliJ, мое дерево исходных текстов выглядит так:
источник
Вероятно, это немного зависит от ваших мотивов не отображать их, но если единственная причина в том, что вы не хотите загрязнять общедоступный интерфейс вещами, предназначенными только для тестирования (или какими-то другими внутренними вещами), я бы поместил методы в отдельный публичный интерфейс, и потребители «скрытых» методов используют этот интерфейс. Это не помешает другим использовать интерфейс, но я не вижу причин, почему вы должны это делать.
Для модульных тестов, и если это возможно без переписывания лота, следуйте советам использовать тот же пакет.
источник
Как объяснили другие, в Java нет такого понятия, как «подпакет»: все пакеты изолированы и ничего не наследуют от своих родителей.
Простой способ получить доступ к защищенным членам класса из другого пакета - это расширить класс и переопределить члены.
Например, чтобы получить доступ
ClassInA
к пакетуa.b
:создайте в этом пакете класс, который переопределяет нужные вам методы
ClassInA
:Это позволяет вам использовать переопределяющий класс вместо класса в другом пакете:
Обратите внимание, что это работает только для защищенных членов, которые видимы для расширяющих классов (наследование), а не для закрытых для пакета членов, которые видимы только для подчиненных / расширяющих классов в одном и том же пакете. Надеюсь, это кому-нибудь поможет!
источник
В большинстве ответов здесь говорится, что в Java нет такого понятия, как подпакет, но это не совсем точно. Этот термин был в Спецификации языка Java еще в Java 6, и, вероятно, еще в далеком прошлом (кажется, не существует свободно доступной версии JLS для более ранних версий Java). Язык вокруг подпакетов не сильно изменился в JLS со времени Java 6.
Java 13 JLS :
Понятие подпакета является актуальным, так как обеспечивает соблюдение ограничений именования между пакетами и классами / интерфейсами:
Тем не менее, это ограничение именования является единственным значением, придаваемым подпакетам языком:
В этом контексте мы можем ответить на сам вопрос. Поскольку в явном виде нет специальных отношений доступа между пакетом и его подпакетом или между двумя различными подпакетами родительского пакета, в языке нет способа сделать метод видимым для двух различных пакетов запрошенным способом. Это задокументированное, намеренное проектное решение.
Либо метод можно сделать общедоступным, и все пакеты (включая
odp.proj
иodp.proj.test
) смогут получить доступ к указанным методам, либо метод можно сделать частным пакетом (видимость по умолчанию), и весь код, которому требуется прямой доступ к нему, должен быть помещен в тот же (суб) пакет, что и метод.Тем не менее, очень стандартная практика в Java - помещать тестовый код в тот же пакет, что и исходный код, но в другом месте файловой системы. Например, в инструменте сборки Maven условием было бы поместить эти исходные и тестовые файлы в
src/main/java/odp/proj
иsrc/test/java/odp/proj
, соответственно. Когда инструмент сборки компилирует это, оба набора файлов оказываются вodp.proj
пакете, но толькоsrc
файлы включены в производственный артефакт; тестовые файлы используются только во время сборки для проверки рабочих файлов. С этой настройкой тестовый код может свободно обращаться к любому пакету частного или защищенного кода кода, который он тестирует, так как они будут в одном пакете.В случае, если вам нужен общий доступ к коду между подпакетами или пакетами одного уровня, который не является тестовым / производственным вариантом, одним из решений, которое я видел в некоторых библиотеках, является размещение этого общего кода как общедоступного, но документа, который предназначен для внутренней библиотеки. использовать только.
источник
Не помещая модификатор доступа перед методом, вы говорите, что это закрытый пакет.
Посмотрите на следующий пример.
источник
С классом PackageVisibleHelper и сохранением его приватности до замораживания PackageVisibleHelperFactory мы можем вызывать метод launchA (с помощью PackageVisibleHelper) где угодно :)
источник