47
Библиотека также является набором файлов с классами. В каждом файле имеется один public-класс с любым количеством классов, не имеющих спецификатора public. Если вы хотите объявить, что все эти компоненты (хранящиеся в отдельных файлах .java и .class) связаны друг с другом, воспользуйтесь ключевым словом package.
Директива packageдолжнанаходиться в первой незакомментированной строке файла. Так, команда.
package access;
означает, что данный компилируемый модуль входит в библиотеку с именем access. Иначе говоря, вы указываете, что открытый класс в этом компилируемом модуле принадлежит имени mypackage и, если кто-то захочет использовать его, ему придется полностью записать или имя класса, или директиву import с access (конструкция, указанная выше). Заметьте, что по правилам Java имена пакетов записываются только строчными буквами.
Предположим, файл называется MyClass.java. Он может содержать один и только один открытый класс (public), причем последний должен называться MyClass (с учетом регистра символов):
//: access/mypackage/MyClass java
package access.mypackage;
public class MyClass {11...
} ///.-
Если теперь кто-то захочет использовать MyClass или любые другие открытые классы из пакета access, ему придется использовать ключевое слово import, чтобы имена из access стали доступными. Возможен и другой вариант — записать полное имя класса:
//: access/QualifiedMyClass java
public class QualifiedMyClass {
public static void main(String[] args) { access mypackage.MyClass m =
new access mypackage.MyClass();
}
} ///:-
С ключевым словом import решение выглядит гораздо аккуратнее:
II: access/ImportedMyClass.java
import access.mypackage.*:
public class ImportedMyClass {
public static void main(String[] args) { MyClass m = new MyClassO:
}
} ///
Ключевые слова package и import позволяют разработчику библиотеки организовать логическое деление глобального пространства имен, предотвращающее конфликты имен независимо от того, сколько людей подключится к Интернету и начнет писать свои классы на Java.
Создание уникальных имен пакетов
Вы можете заметить, что, поскольку пакет на самом деле никогда не «упаковывается» в единый файл, он может состоять из множества файлов .class, что способно привести к беспорядку, может, даже хаосу. Для предотвращения проблемы логично было бы разместить все файлы .class конкретного пакета в одном каталоге, то есть воспользоваться иерархической структурой файловой системы. Это первый способ решения проблемы нагромождения файлов в Java; о втором вы узнаете при описании утилиты jar.
Размещение файлов пакета в отдельном каталоге решает две другие задачи: создание уникальных имен пакетов и обнаружение классов, потерянных в «дебрях» структуры каталогов. Как было упомянуто в главе 2, проблема решается «кодированием» пути файла в имени пакета. По общепринятой схеме первая часть имени пакета должна состоять из перевернутого доменного имени разработчика класса. Так как доменные имена Интернета уникальны, соблюдение этого правила обеспечит уникальность имен пакетов и предотвратит конфликты. (Только если ваше доменное имя не достанется кому-то другому, кто начнет писать программы на Java под тем же именем.) Конечно, если у вас нет собственного доменного имени, для создания уникальных имен пакетов придется придумать комбинацию с малой вероятностью повторения (скажем, имя и фамилия). Если же вы решите публиковать свои программы на Java, стоит немного потратиться на получение собственного доменного имени.
Вторая составляющая — преобразование имени пакета в каталог на диске компьютера. Если программе во время исполнения понадобится загрузить файл .class (что делается динамически, в точке, где программа создает объект определенного класса, или при запросе доступа к статическим членам класса), она может найти каталог, в котором располагается файл .class.
Интерпретатор Java действует по следующей схеме. Сначала он проверяет переменную окружения CLASSPATH (ее значение задается операционной системой, а иногда программой установки Java или инструментарием Java). CLASSPATH содержит список из одного или нескольких каталогов, используемых в качестве корневых при поиске файлов .class. Начиная с этих корневых каталогов, интерпретатор берет имя пакета и заменяет точки на слеши для получения полного пути (таким образом, директива package foo.bar.baz преобразуется в foo\bar\baz, foo/bar/baz или что-то еще в зависимости от вашей операционной системы). Затем полученное имя присоединяется к различным элементам CLASSPATH. В указанных местах ведется поиск файлов .class, имена которых совпадают с именем создаваемого программой класса. (Поиск также ведется в стандартных каталогах, определяемых местонахождением интерпретатора Java.)
Чтобы понять все сказанное, рассмотрим мое доменное имя: MindView.net. Обращая его, получаем уникальное глобальное имя для моих классов: net. mindview. (Расширения com, edu, org и другие в пакетах Java прежде записывались в верхнем регистре, но начиная с версии Java 2 имена пакетов записываются только строчными буквами.) Если потребуется создать библиотеку с именем simple, я получаю следующее имя пакета:
package net.mindview.simple,
Теперь полученное имя пакета можно использовать в качестве объединяющего пространства имен для следующих двух файлов:
//: net/mindview/simple/Vector.java
// Создание пакета
package net mindview simple,
public class Vector { public VectorО {
System out printlnCnet mindview.simple.Vector");
}
} ///:-
Как упоминалось ранее, директива package должна находиться в первой строке исходного кода. Второй файл выглядит почти так же:
//: net/mindview/simple/List java
// Создание пакета
package net.mindview simple;
public class List { public ListO {
System.out pri ntln("net.mi ndvi ew.si mple.Li st"),
}
} /// ~
В моей системе оба файла находятся в следующем подкаталоге:
С \DOC\JavaT\net\mindview\simple
Если вы посмотрите на файлы, то увидите имя пакета net.mindview.simple, но что с первой частью пути? О ней позаботится переменная окружения CLAS- SPATH, которая на моей машине выглядит следующим образом: