Java-пакеты не являются вложенными. Хотя их имена могут иметь общие префиксы, это не имеет значения в языке программирования Java.
Также тот факт, что их файлы классов хранятся во вложенных каталогах, когда хранилище является файловой системой, не имеет никакого дополнительного значения. Когда классы хранятся в jar-файле, они хранятся с именами записей, соответствующими их квалифицированным именам, без фактического формирования каталогов вообще (хотя многие инструменты предпочитают представлять их как будто они находятся в иерархической структуре для имитации файловой системы).
Таким образом, пакеты com.company.project.tools.useless
и com.company.project.tools
не имеют никакого отношения вообще. В то время как мы, люди, склонны организовывать код таким образом, что здесь можно предположить семантические отношения (что хорошо), на техническом уровне их нет. Между ними нет относительной адресации, и нет никаких дополнительных прав доступа по сравнению с любыми двумя другими пакетами. Фактически, оба пакета могут быть частью двух разных модулей (начиная с Java 9) с еще меньшими правами доступа по сравнению с двумя другими пакетами с менее похожими именами.
Стандартный подход к использованию класса из другого пакета заключается в использовании com.company.project.Tools.Useless.Foo;
с последующим использованием Foo
в классе.
Не совсем ясно, какую проблему вы видите с этим, то есть, что, как предполагается, должно означать «поскольку импорт связывает его с текущей областью действия». Само существование оператора import
не влияет на код. Все, что он говорит компилятору, - это как разрешить вхождения простого имени Foo
, если в области видимости нет другого Foo
.
Другими словами, локальные области все еще имеют приоритет, даже включая унаследованные элементы. Кроме того, в местах, где могут появляться переменные и типы, переменные имеют приоритет. Например. для вхождения Foo.bar()
переменная с именем Foo
будет иметь приоритет, локальная переменная перед переменными-членами того же типа, внешний класс или унаследованные. В противном случае будут использоваться типы элементов, внешние типы или унаследованные типы элементов. Только если ни один из них не существует, оператор import
будет использоваться для разрешения Foo
.
Само собой разумеется, вам следует избегать иметь так много предметов с одинаковым простым именем, что вам придется подумать о деталях процесса разрешения. Вот почему соглашения об именах предлагают начинать имена переменных со строчной буквы, а имена классов - с заглавной.
И да, избегайте давать классам одно и то же простое имя. Как только вы столкнетесь с обоими классами в пределах одного модуля компиляции, вы не сможете получить доступ к одному из них с его (полностью) квалифицированным именем во всем модуле компиляции. (Использование *
в импорте никак не поможет при таком сценарии)
Как объяснено, термин «полностью» в Java устарел, поскольку квалифицированные имена всегда полны.