Создание уникальных имен пакетов
Обратите внимание, что пакет, на самом деле, не всегда располагается в единичном файле, и может быть собран из большого количества .class файлов - и, в результате, получится небольшой беспорядок. Чтобы не допустить этого, по логике вещей, нужно поместить все .class файлы в один пакет и в отдельный каталог, с помощью иерархии файловой структуры Вашей операционной системы. Это один из способов - как Java решает проблему нагромождения файлов; С другим способом Вы познакомитесь позже, когда будет описана утилита jar.
Сборка файлов пакета в отдельном каталоге решает две другие проблемы: создания уникальных имен пакета, и поиска тех классов, которые могут быть скрыты где угодно в структуре каталогов. Это достигается, как было описано в Главе 2, с помощью указания пути к .class файлу в имени пакета, после ключевого слова package. Компилятор навязывает именно такую форму, но по соглашению, первая часть имени пакета зарезервирована - это доменное имя создателя класса в интернет. Поскольку доменные имена в интернете гарантированно являются уникальными, то, следуя этому соглашению, Вы гарантированно получаете уникальные имена пакетов и никогда получите конфликта имен. (Во всяком случае, пока Вы не отдадите это доменное имя кому-нибудь другому, кто начнет писать классы на Java с теми же именами путей, что и у Вас.) Конечно, если у Вас нет доменного имени, Вам придется придумать невероятную комбинацию (например, как Ваши имя и фамилия), для создания уникального имени пакета. Но если Вы решите опубликовывать код на Java, Вам стоит немного напрячься и получить собственное доменное имя.
Также необходимо расположение пакета в отдельном каталоге на Вашей машине. Когда Java программа запустится и потребует загрузки .class файла (что делается динамически, в том месте программы где создается объект соответствующего класса, либо впервые Вы получаете доступ к статическому члену класса), она сможет определить расположение каталога, где находятся .class файлы.
Интерпретатор Java действует следующим образом. Сначала, он ищет переменную среды с именем CLASSPATH (она устанавливается в операционной системе программой установки Java, либо инструментами, основанными на Java, на Вашей машине). CLASSPATH содержит один или более каталогов, которые используются как корневые для поиска .class файлов. Начиная с этого корневого каталога, интерпретатор берет имя пакета и заменяет каждую точку на косую черту для создания имени пути от корня в CLASSPATH (так, например, package foo.bar.baz превратится в foo\bar\baz или foo/bar/baz а, может быть, что-то другое, в зависимости от Вашей операционной системы). Затем это добавляется к различным элементам переменной CLASSPATH. Вот как интерпретатор ищет .class файлы, с именем класса, который Вы пытаетесь создать. (Он также производит поиск в стандартных каталогах, относительно того, где располагается сам интерпретатор).
Чтобы понять это, давайте рассмотрим мое доменное имя - bruceeckel.com. Резервируя его - com.bruceeckel - создаем уникальное глобальное имя для моих классов. (Имена com, edu, org, и т.д., раньше писались с заглавными буквами в пакетах Java, однако это изменилось в Java 2, так что сейчас имя пакета должно быть написано полностью в нижнем регистре.) Теперь если я хочу создать библиотеку с именем simple, у меня получится следующее имя пакета:
package com.bruceeckel.simple;
Теперь это имя пакета может быть использовано, как прикрытие для пространства имен у следующих двух файлов:
//: com:bruceeckel:simple:Vector.java
// Создание пакета.
package com.bruceeckel.simple;
public class Vector { public Vector() { System.out.println( "com.bruceeckel.util.Vector"); } } ///:~
Когда Вы создадите пакет, Вы обнаружите, что выражение package должно быть первой строкой кода после комментариев в файле. Второй файл выглядит следующим образом:
//: com:bruceeckel:simple:List.java
// Создание пакета.
package com.bruceeckel.simple;
public class List { public List() { System.out.println( "com.bruceeckel.util.List"); } } ///:~
Оба этих файла располагаются в подкаталоге на моей машине:
C:\DOC\JavaT\com\bruceeckel\simple
Если Вы вернетесь назад, то увидите имя пакета com.bruceeckel.simple. А что же насчет первой части пути? Об этом заботится переменная CLASSPATH, которая, на моей машине, содержит следующее значение:
CLASSPATH=.;D:\JAVA\LIB;C:\DOC\JavaT
Вы видите, что CLASSPATH содержит несколько альтернативных путей поиска.
Однако, при использовании JAR файлов, есть небольшая разница. Вы должны указывать имя JAR файла в CLASSPATH, а не только путь к нему. Так, для JAR файла grape.jar, Ваша переменная CLASSPATH может содержать:
CLASSPATH=.;D:\JAVA\LIB;C:\flavors\grape.jar
Как только переменная CLASSPATH корректно установлена, следующий файл может располагаться в любом каталоге:
//: c05:LibTest.java
// Использует библиотеку.
import com.bruceeckel.simple.*;
public class LibTest { public static void main(String[] args) { Vector v = new Vector(); List l = new List(); } } ///:~
Когда компилятор встречает выражение import, он начинает поиск с каталогов, указанных в CLASSPATH, там ищет подкаталог com\bruceeckel\simple, а затем, откомпилированный файл с соответствующим именем (Vector.class для Vector и List.class для List). Обратите внимание, что оба класса и необходимые методы в Vector и List должны быть публичными.
Установка переменной CLASSPATH стало как бы испытанием для новичков в Java (так было и для меня, когда я начинал), хотя JDK в Java 2 от Sun стал более умным. Вы увидите, что, после установки, даже если Вы не установили переменную CLASSPATH, Вы сможете компилировать и запускать основные программы на Java. Однако, для компиляции и запуска исходных кодов из этой книги (доступных на CD ROM поставляющемся вместе с книгой, либо на www.BruceEckel.com), Вам нужно будет сделать некоторые модификации переменной CLASSPATH (которые описываются в пакете исходных кодов).