Программа на Java представляет собой набор пакетов (packages). Каждый пакет может включать вложенные пакеты, то есть они образуют иерархическую систему.
Кроме этого, пакеты могут содержать классы и интерфейсы, и таким образом группируют типы, что необходимо сразу для нескольких целей. Во-первых, чисто физически невозможно работать с большим количеством классов, если они "свалены в кучу". Во-вторых, модульная декомпозиция облегчает проектирование системы. К тому же, как будет рассмотрено ниже, существует специальный уровень доступа, позволяющий типам из одного пакета более "тесно" взаимодействовать друг с другом, чем с классами из других пакетов. Таким образом, с помощью пакетов производится логическая группировка типов. Из ООП известно, что большая связность системы, то есть среднее количество классов, с которыми взаимодействует каждый класс, серьезно усложняет развитие и поддержку такой системы.
С применением пакетов гораздо проще эффективно организовать взаимодействие подсистем друг с другом.
Наконец, каждый пакет имеет свое пространство имен, что позволяет создавать одноименные классы в различных пакетах. Таким образом, разработчикам не приходится тратить время на разрешение конфликта имен.
Элементы пакета
Еще раз повторим, что элементами пакета являются вложенные пакеты и типы (классы и интерфейсы). Одноименные элементы запрещены, то есть не может быть одноименных класса и интерфейса или вложенного пакета и типа. В противном случае возникнет ошибка компиляции.
Например, в JDK 1.0 пакет java содержал следующие пакеты: applet, awt, io, lang, net, util; и не содержал ни одного типа. Пакет java.awt содержал вложенный пакет image и 46 классов и интерфейсов.
Составное имя любого элемента пакета составляется из составного имени этого пакета и простого имени элемента. Например, для класса Object в пакете java.lang составным именем будет java.lang.Object, а для пакета image в пакете java.awt - java.awt.image.
Иерархическая структура пакетов была введена для удобства организации связанных пакетов, однако вложенные пакеты или соседние, то есть вложенные в один и тот же пакет, не имеют никаких дополнительных связей между собой, кроме ограничения на несовпадение имен. Например, пакеты space.sun, space.sun.ray, space.moon и factory.store совершенно "равны" между собой, и типы из одного из этих пакетов не имеют никакого особенного доступа к типам других пакетов.
Платформенная поддержка пакетов
Простейшим способом организации пакетов и типов является обычная файловая структура. Рассмотрим вырожденный пример, когда все пакеты, исходный и бинарный код располагаются в одной директории и ее поддиректориях.
В этой корневой директории должна быть папка java, соответствующая основному пакету языка, а в ней, в свою очередь, вложенные папки applet, awt, io, lang, net, util.
Предположим, разработчик работает над моделью солнечной системы, для чего создал классы Sun, Moon и Test, и расположил их в пакете space.sunsystem. В таком случае в корневой директории будет папка space, которая будет соответствовать одноименному пакету, а в ней - папка sunsystem, в которой хранятся классы этого разработчика.
Как известно, исходный код располагается в файлах с расширением .java, а бинарный - с расширением .class. Таким образом, содержимое папки sunsystem может выглядеть следующим образом:
Moon.java
Moon.class
Sun.java
Sun.class
Test.java
Test.class
Другими словами, исходный код классов
space.sunsystem.Moon
space.sunsystem.Sun
space.sunsystem.Test
хранится в файлах
space\sunsystem\Moon.java
space\sunsystem\Sun.java
space\sunsystem\Test.java
а бинарный код - в соответствующих .class-файлах.
Обратите внимание, что преобразование имен пакетов в файловые пути потребовало замены разделителя . (точки) на символ разделитель файлов (для Windows это обратный слеш \). Такое преобразование легко сможет сделать как компилятор для поиска исходных текстов и бинарного кода, так и виртуальная машина для загрузки классов и интерфейсов.
Обратите внимание, что было бы ошибкой запускать Java прямо из папки space\sunsystem и пытаться обращаться к классу Test, несмотря на то, что файл-описание лежит именно в ней. Необходимо подняться на два уровня директорий выше, чтобы Java, построив путь из имени пакета, смогла обнаружить нужный файл.
Кроме того, немаловажно то, что Java всегда различает регистр идентификаторов, а значит, и названия файлов и директорий должны точно отвечать запрограммированным именам. Хотя в некоторых случаях операционная система может обеспечить доступ, невзирая на регистр, но при изменении обстоятельств расхождения могут привести к сбоям.
Если статья была Вам полезна, ставьте пальцы вверх и подписывайтесь. Оставляйте свои пожелания и вопросы в комментариях, с удовольствием отвечу.
#java #it #пакеты #с нуля