Java для школьников. Занятие №8. Понятие пакетов в Java

Предыдущее занятие Следущее занятие

До сих пор мы имели дело с небольшими программы на языке программирования Java. Однако, на Java можно писать не только простенькие программы. Говорят, что Java - язык профессионалов и с помощью этого языка программирования (ЯП) можно выполнять сложнейшие проекты, над которыми работают целые команды разработчиков. И это действительно так. Давайте рассмотрим на сегодняшнем занятии еще один основополагающий принцип, помогающий писать на Java профессиональные программы.

Итак, технологии Java позволяют разбить большую программу на отдельные "части" (модули) и использовать принцип "разделения" в написании кода. При этом каждая программная часть может разрабатываться и отлаживаться отдельно от других. В этом смысле Java, конечно, не единственный язык, использующий подобные технологии (разделение кода так или иначе используется в Pascal, C, C++ и других ЯП). В Java для реализации этого принципа используется понятие пакета.

Далее. Каждый пакет создает свое, так называемое, "пространство имен". Это означает, что имена пакетов и имена классов в пакете должны быть уникальными. Имена классов в разных пакетах могут совпадать, но это будут разные программные единицы. Таким образом, каждый программист, разрабатывая свою систему классов, придумывает имена только для своих пакетов, классов и их методов, а какие имена будут использовать другие программисты в своих пакетах, его не очень интересует (пока, конечно, он не будет их использовать в своих программах).

Процитируем Б.Эккеля [1]:

Файлы с исходными текстами на Java часто называют компилируемым модулем. Имя каждого компилируемого модуля должно завершаться суффиксом (расширением) .java, а внутри него может находиться открытый (public) класс, имеющий то же имя, что и файл (с заглавной буквы, но без расширения .java). Любой компилируемый модуль может содержать не более одного открытого класса, иначе компилятор сообщит об ошибке. Остальные классы модуля, если они там есть, скрыты от окружающего мира - они не являются открытыми (public) и считаются "вспомогательными" по отношению к главному открытому классу.
В результате компиляции для каждого класса, определенного в файле .java, создается класс с тем же именем, но с расширением .class. Таким образом, при компиляции нескольких файлов .java может появиться целый ряд файлов с расширением .class....
Библиотека (пакет) также является набором файлов с классами. В каждом файле имеется один public-класс с любым количеством классов, не имеющих спецификатора public. Если вы хотите объявить, что все эти компоненты (хранящиеся в отдельных файлах .java и .class) связаны друг с другом, воспользуйтесь ключевым словом package.
Директива (команда) package должна находиться в первой незакомментированной строке файла с исходными текстами на Java.

Если перейти к применению директивы package, то

package mypackage.mathprog;

означает, что данный компилируемый модуль входит в пакет с именем mypackage.mathprog. Точка в имени пакета говорит о том, что пакеты могут "лежать" один в другом. На практике это означает, что файлы с байт-кодом программ этого пакета будут располагаться в каталоге файловой системы mypackages\mathprog (mypackages/mathprog в Unix). Распределяя пакеты по каталогам программист наводит порядок в их структуре (по понятным причинам количество классов в пакете может быть достаточно большим). Точки в именах пакетов для классов Java, использованы и разработчиками языка, что однозначно помогает разобраться в структуре и расположении классов языка. Отметим, что для соблюдения принципа уникальности имен классов используют негласное правило - в имени пакета используется доменное имя его разработчика, записанное наоборот, например

package ru.learn2prog.mypackage.mathprog;

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

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

Для объяснения того, как использовать различные директивы компилятора javac при применении package, приведем цитату из книги Д.Фленагана (см.[3]):

При компиляции модуля, использующего директиву package, используется, например, команда в консоли:
javac -d каталог имя_файла.java
Ключ
-d каталог
Устанавливает каталог, в котором (или в подкаталогах которого) нужно сохранить файлы классов. По умолчанию javac сохраняет файлы .class в том же каталоге, где находятся файлы .java (компилируемые модули). Если задан ключ -d, каталог рассматривается как корневой в иерархии классов. Так команда
javac -d /java/classes Checkers.java
поместить класс Checkers.class в каталог /java/classes, если в файле Checkers.java нет оператора package.
Если же в исходном файле .java обозначена принадлежность к пакету
package com.david.flanagan.games;
то файл .class сохраняется в каталоге /java/classes/com/david/flanagan/games
При этом компилятор javac автоматически создаст все нужные каталоги.

На практике наиболее часто используется команда, подобная приведенной выше -

javac -d . имя_файла.java

где точка после ключа -d означает, что каталоги для классов, согласно директивы package, будут созданы начиная с текущего каталога.
Отметим, что при использовании пакетов изменяется строка запуска программы. Так, если использовать для компиляции строку

javac -d /java/classes Checkers.java

и НЕ использовать в файле .java директиву package, то для запуска программы в виртуальной машине необходима команда

java java.classes.Checkers

Таким образом правила обращения с пакетами выглядят следующим образом:

  • для создания своего пакета (библиотеки) используйте в первой незакомментированной строке файла .java ключевое слово package;
  • выберите уникальное имя для своего пакета. Обычно, чтобы соблюдалась уникальность в имени пакета, пользуются своим доменным именем, записанным наоборот;
  • для компиляции используйте команду javac с ключом -d.
  • будьте внимательны - при использовании пакетов изменяется строка запуска программы.

Пакетами пользуются еще и для того, чтобы добавить к уже знакомым нам правам доступа к членам класса private и public еще один "пакетный" уровень. Это значит, что если член класса не отмечен никаким спецификатором доступа (см. предыдущее занятие - конструктор по-умолчанию Box()), к такому полю или методу может обратиться любой метод любого класса из того же пакета (см. [2]).


Литература:
1. Б.Эккель "Философия Java", 4-е издание, с.154
2. Хабибуллин "Самоучитель JAVA 2". -СПб.: БХВ-Петербург, 2005, с.100
3. Д.Фленаган, "Java справочник","O'Relly" - "Символ", 2004г., 4-е издание, с.262