Spec-Zone .ru
спецификации, руководства, описания, API
Содержание | Предыдущий | Следующий | Индекс Спецификация языка Java
Второй Выпуск


ГЛАВА 7

Пакеты


Программы организуются как наборы пакетов. У каждого пакета есть свой собственный набор имен для типов, который помогает предотвратить конфликты имен. Высокоуровневый тип доступен (§6.6) вне пакета, который объявляет это, только если тип объявляется public.

Структура именования для пакетов является иерархической (§7.1). Элементы пакета являются классом и интерфейсными типами (§7.6), которые объявляются в единицах компиляции пакета, и подпакетов, которые могут содержать единицы компиляции и собственные подпакеты.

Пакет может быть сохранен в файловой системе (§7.2.1) или в базе данных (§7.2.2). У пакетов, которые сохранены в файловой системе, есть определенные ограничения на организацию их единиц компиляции, чтобы позволить простой реализации находить классы легко.

Пакет состоит из многих единиц компиляции (§7.3). Единица компиляции автоматически имеет доступ ко всем типам, объявленным в его пакете, и также автоматически импортирует все открытые типы, объявленные в предопределенном пакете java.lang.

Для маленьких программ и случайной разработки, пакет может быть неназванным (§7.4.2) или иметь простое имя, но если код должен быть широко распределен, уникальные имена пакета должны быть выбраны (§7.7). Это может предотвратить конфликты, которые иначе произошли бы, если бы две группы разработки, оказалось, выбрали то же самое имя пакета, и эти пакеты должны были позже использоваться в единственной программе.

7.1 Элементы пакета

Элементы пакета являются подпакетами и всем верхним уровнем (§7.6) класс (§8) и высокоуровневый интерфейс (§9) типы, объявленные во всех единицах компиляции (§7.3) пакета.

Например, в Прикладном программном интерфейсе Java:

Если полностью определенное имя (§6.7) пакета является P, и Q является подпакетом P, то P.Q является полностью определенным именем подпакета.

Пакет, возможно, не содержит два элемента того же самого имени, или ошибка времени компиляции заканчивается.

Вот некоторые примеры:

Иерархическая структура именования для пакетов предназначается, чтобы быть удобной для того, чтобы организовать связанные пакеты стандартным способом, но не имеет никакого значения сам по себе кроме запрета на пакет, имеющий подпакет с тем же самым простым именем как высокоуровневый тип (§7.6) объявленный в том пакете. Между названным пакетом нет никакого специального отношения доступа oliver и другой пакет называют oliver.twist, или между пакетами называется evelyn.wood и evelyn.waugh. Например, код в пакете называют oliver.twist не имеет никакого лучшего доступа к типам, объявленным в пределах пакета oliver чем код в любом другом пакете.

7.2 Поддержка узла Пакетов

Каждый узел определяет, как пакеты, единицы компиляции, и подпакеты создаются и сохранены, и какие единицы компиляции заметны (§7.3) в определенной компиляции.

Наблюдательность единиц компиляции поочередно определяет, какие пакеты заметны, и какие пакеты находятся в контексте.

Пакеты могут быть сохранены в локальной файловой системе в простых реализациях платформы Java. Другие реализации могут использовать распределенную файловую систему или некоторую форму базы данных, чтобы сохранить исходный и/или двоичный код.

7.2.1 Хранение Пакетов в Файловой системе

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

com
gls
jag
java
wnj
где каталог java содержал бы пакеты Прикладного программного интерфейса Java; каталоги jag, gls, и wnj мог бы содержать пакеты что три из авторов этой спецификации, создаваемой для их персонального использования и совместно использовать друг с другом в пределах этой небольшой группы; и каталог com содержал бы пакеты, обеспеченные от компаний, которые использовали соглашения, описанные в §7.7, чтобы генерировать уникальные имена для их пакетов.

Продолжая пример, каталог java содержал бы, среди других, следующих подкаталогов:

applet	
awt
io
lang
net
util
соответствие пакетам java.applet, java.awt, java.io, java.lang, java.net, и java.util это определяется как часть Прикладного программного интерфейса Java.

Все еще продолжая пример, если мы должны были смотреть в каталоге util, мы могли бы видеть следующие файлы:

BitSet.java				Observable.java
BitSet.class				Observable.class
Date.java				Observer.java
Date.class				Observer.class
...
где каждый из .java файлы содержат источник для единицы компиляции (§7.3), который содержит определение класса или интерфейса, двоичный файл которого скомпилированная форма содержится в соответствии .class файл.

Под этой простой организацией пакетов реализация платформы Java преобразовала бы имя пакета в путь, связывая компоненты имени пакета, помещая разделитель имени файла (индикатор каталога) между смежными компонентами.

Например, если эта простая организация использовалась на системе UNIX, где разделитель имени файла /, имя пакета:

jag.scrabble.board
был бы преобразован в имя каталога:

jag/scrabble/board
и:

com.sun.sunsoft.DOE
был бы преобразован к имени каталога:

com/sun/sunsoft/DOE

Имя компонента имени пакета или имя класса могли бы содержать символ, который не может правильно появиться в обычном имени каталога файловой системы узла, таком как символ Unicode на системе, которая позволяет только символы ASCII в именах файлов. Как соглашение, при использовании символа можно оставить, скажем, @ символ, сопровождаемый четырьмя шестнадцатеричными цифрами, дающими числовое значение символа, как в \uescape xxxx (§3.3), так, чтобы имя пакета:
children.activities.crafts.papierM\u00e2ch\u00e9
который может также быть записан, используя полный Unicode как:

children.activities.crafts.papierMâché
мог бы быть отображен на имя каталога:

children/activities/crafts/papierM@00e2ch@00e9
Если @ символ не является допустимым символом в имени файла для некоторой данной файловой системы узла, тогда некоторый другой символ, который не допустим в идентификаторе, мог использоваться вместо этого.

7.2.2 Хранение Пакетов в Базе данных

Хост-система может сохранить пакеты и их единицы компиляции и подпакеты в базе данных.

Такая база данных не должна ввести дополнительные ограничения (§7.6) для единиц компиляции в основанных на файле реализациях. Например, система, которая использует базу данных, чтобы сохранить пакеты, возможно, не осуществляет максимум одного public класс или интерфейс на единицу компиляции.

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

7.3 Единицы компиляции

CompilationUnit является целевым символом (§2.1) для синтаксической грамматики (§2.3) программ Java. Это определяется следующим производством:

Типы, объявленные в различных единицах компиляции, могут зависеть друг от друга, циркулярного. Компилятор Java должен расположить скомпилировать все такие типы одновременно.

Единица компиляции состоит из трех частей, каждая из которых является дополнительной:

То, какие единицы компиляции заметны, определяется хост-системой. Однако, все единицы компиляции пакета java и его подпакеты lang и io должно всегда быть заметным. Наблюдательность единицы компиляции влияет на наблюдательность своего пакета (§7.4.3).

Каждая единица компиляции автоматически и неявно импортирует каждый public имя типа объявляется предопределенным пакетом java.lang, так, чтобы имена всех тех типов были доступны как простые имена, как описано в §7.5.3.

7.4 Объявления пакета

Объявление пакета, кажется, в пределах единицы компиляции указывает на пакет, которому принадлежит единица компиляции.

7.4.1 Названный Пакетами

Объявление пакета в единице компиляции определяет имя (§6.2) пакета, которому принадлежит единица компиляции.

Имя пакета, упомянутое в объявлении пакета, должно быть полностью определенным именем (§6.7) пакета.

7.4.2 Неназванные Пакеты

Единица компиляции, у которой нет никакого объявления пакета, является частью неназванного пакета.

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

Как пример, единица компиляции:

class FirstCall {
	public static void main(String[] args) {
		System.out.println("Mr. Watson, come here. "
						+ "I want you.");
	}
}
определяет очень простую единицу компиляции как часть неназванного пакета.

Реализация платформы Java должна поддерживать по крайней мере один неназванный пакет; это может поддерживать больше чем один неназванный пакет, но не обязано делать так. То, какие единицы компиляции находятся в каждом неназванном пакете, определяется хост-системой.

В реализациях платформы Java, которые используют иерархическую файловую систему для того, чтобы сохранить пакеты, одна типичная стратегия состоит в том, чтобы связать неназванный пакет с каждым каталогом; только один неназванный пакет заметен за один раз, а именно, тот, который связывается с "текущим рабочим каталогом." Точное значение "текущего рабочего каталога" зависит от хост-системы.

Неназванные пакеты обеспечиваются платформой Java преимущественно для удобства, разрабатывая маленькие или временные приложения или только начиная разработку.

7.4.3 Наблюдательность Пакета

Пакет заметен если и только если также:

Можно завершить из правила выше и от требований к заметным единицам компиляции, что пакеты java, java.lang, и java.io всегда заметны.

7.4.4 Контекст Объявления Пакета

Контекст объявления заметного (§7.4.3) высокоуровневого пакета является всеми заметными единицами компиляции (§7.3). Объявление пакета, который не заметен, никогда не находится в контексте. Объявления подпакета никогда не находятся в контексте.

Из этого следует, что пакет java всегда находится в контексте (§6.3).

Объявления пакета никогда тень другие объявления.

7.5 Объявления импорта

Объявление импорта позволяет именованному типу быть упомянутым простым именем (§6.2), который состоит из единственного идентификатора. Без использования соответствующего import объявление, единственный способ обратиться к типу, объявленному в другом пакете, должно использовать полностью определенное имя (§6.7).

Объявление единственного импорта типа (§7.5.1) импортирует единственный именованный тип, упоминая его каноническое имя. Объявление "импорт типа по требованию" (§7.5.2) импортирует все доступные типы именованного типа или пакета как необходимый.

Контекст типа, импортированного объявлением единственного импорта типа (§7.5.1) или объявлением "импорт типа по требованию" (§7.5.2), является всем классом и интерфейсными описаниями типа (§7.6) в единице компиляции, в которой появляется объявление импорта.

import объявление делает типы доступными их простыми именами только в пределах единицы компиляции, которая фактически содержит import объявление. Контекст объектов (ов), которые это представляет определенно, не включает package оператор, другой import объявления в текущей единице компиляции, или других единицах компиляции в том же самом пакете. См. §7.5.4 для иллюстративного примера.

7.5.1 Объявление единственного импорта типа

Объявление единственного импорта типа импортирует единственный тип, давая его каноническое имя, делая его доступный под простым именем в классе и интерфейсных объявлениях единицы компиляции, в которой появляется объявление импорта единственного типа.

TypeName должен быть каноническим именем класса или интерфейсного типа; ошибка времени компиляции происходит, если именованный тип не существует. Именованный тип должен быть доступным (§6.6), или ошибка времени компиляции происходит.

Объявление d единственного импорта типа в единице компиляции c пакета p, который импортирует тип, названный n тенями объявления:

всюду по c.

Пример:

import java.util.Vector;
вызывает простое имя Vector быть доступным в пределах класса и интерфейсных объявлений в единице компиляции. Таким образом, простое имя Vector обращается к типу Vector в пакете java.util во всех местах, где это не затенено (§6.3.1) или затененный (§6.3.2) объявлением поля, параметра, локальной переменной, или объявления вложенного типа с тем же самым именем.

Если два объявления единственного импорта типа в той же самой единице компиляции пытаются импортировать типы с тем же самым простым именем, то ошибка времени компиляции происходит, если два типа не являются тем же самым типом, когда двойное объявление игнорируется. Если другой высокоуровневый тип с тем же самым простым именем иначе объявляется в текущей единице компиляции кроме объявлением "импорт типа по требованию" (§7.5.2), то ошибка времени компиляции происходит.

Так пример программы:

import java.util.Vector;
class Vector { Object[] vec; }
вызывает ошибку времени компиляции из-за двойного объявления Vector, так что делает:

import java.util.Vector;
import myVector.Vector;
где myVector пакет, содержащий единицу компиляции:

package myVector;
public class Vector { Object[] vec; }
Компилятор отслеживает типы их двоичными именами (§13.1).

Отметьте, что оператор импорта не может импортировать подпакет, только тип. Например, это не работает, чтобы попытаться импортировать java.util и затем используйте имя util.Random обратиться к типу java.util.Random:

import java.util;		// incorrect: compile-time error
class Test { util.Random generator; }

7.5.2 Объявление "Импорт типа по требованию"

Объявление "импорт типа по требованию" позволяет всему доступному (§6.6) типы, объявленные в типе или пакете, названном каноническим именем быть импортированным как необходимый.

Это - ошибка времени компиляции для объявления "импорт типа по требованию", чтобы назвать тип или пакет, который не доступен. Два или больше объявления "импорт типа по требованию" в той же самой единице компиляции могут назвать тот же самый тип или пакет; эффект состоит в том, как будто было точно одно такое объявление. Это не ошибка времени компиляции, чтобы назвать текущий пакет или java.lang в объявлении "вводят импорт по требованию". Объявление "импорт типа по требованию" игнорируется в таких случаях

Объявление "импорт типа по требованию" никогда не заставляет никакое другое объявление быть затененным.

Пример:

import java.util.*;
вызывает простые имена всех public типы объявляются в пакете java.util быть доступным в пределах класса и интерфейсных объявлений единицы компиляции. Таким образом, простое имя Vector обращается к типу Vector в пакете java.util во всех местах в единице компиляции, где то описание типа не затенено (§6.3.1) или затененный (§6.3.2). Объявление могло бы быть затенено объявлением единственного импорта типа типа, простое имя которого Vector; названным типом Vector и объявленный в пакете, которому принадлежит единица компиляции; или любые вложенные классы или интерфейсы. Объявление могло бы быть затенено объявлением поля, параметра, или названной локальной переменной Vector (Это было бы необычно для любого из этих условий произойти.)

7.5.3 Автоматический Импорт

Каждая единица компиляции автоматически импортирует весь из public имена типов объявляются в предопределенном пакете java.lang, как будто объявление:

import java.lang.*;
казавшийся в начале каждой единицы компиляции, сразу после любого package оператор.

7.5.4 Странный Пример

Имена пакета и имена типов обычно отличаются в соответствии с соглашениями о присвоении имен, описанными в §6.8. Однако, в изобретенном примере, где есть вопреки обычаям именованный пакет Vector, который объявляет a public класс называют Mosquito:

package Vector;
public class Mosquito { int capacity; }
и затем единица компиляции:

package strange.example;
import java.util.Vector;
import Vector.Mosquito;
class Test {
	public static void main(String[] args) {
		System.out.println(new Vector().getClass());
		System.out.println(new Mosquito().getClass());
	}
}
объявление единственного импорта типа (§7.5.1) импорт класса Vector от пакета java.util не предотвращает имя пакета Vector от появления и быть правильно распознанным в последующем import объявления. Пример компилирует и производит вывод:

class java.util.Vector
class Vector.Mosquito

7.6 Высокоуровневые Описания типа

Высокоуровневое описание типа объявляет высокоуровневый тип класса (§8) или высокоуровневый тип интерфейса (§9):

По умолчанию высокоуровневые типы, объявленные в пакете, доступны только в пределах единиц компиляции того пакета, но тип, как могут объявлять, public предоставить доступ к типу от кода в других пакетах (§6.6, §8.1.1, §9.1.1).

Контекст высокоуровневого типа является всеми описаниями типа в пакете, в котором объявляется высокоуровневый тип.

Если высокоуровневый тип по имени T объявляется в единице компиляции пакета, полностью определенное имя которого является P, то полностью определенное имя типа является P.T. Если тип объявляется в неназванном пакете (§7.4.2), то у типа есть полностью определенное имя T.

Таким образом в примере:

package wnj.points;
class Point { int x, y; }
полностью определенное имя класса Point wnj.points.Point.

Реализация платформы Java должна отследить типы в пределах пакетов их двоичными именами (§13.1). Многократные способы назвать тип должны быть расширены до двоичных имен, чтобы удостовериться, что такие имена понимаются как обращающийся к тому же самому типу.

Например, если единица компиляции содержит объявление единственного импорта типа (§7.5.1):

import java.util.Vector;
тогда в пределах той единицы компиляции простое имя Vector и полностью определенное имя java.util.Vector обратитесь к тому же самому типу.

Когда пакеты сохранены в файловой системе (§7.2.1), хост-система может хотеть осуществлять ограничение, что это - ошибка времени компиляции, если тип не находится в файле под именем, составленным из имени типа плюс расширение (такой как .java или .jav) если любое из следующего является истиной:

Это ограничение подразумевает, что должен быть самое большее один такой тип на единицу компиляции. Это ограничение облегчает для компилятора для языка программирования Java или реализации виртуальной машины Java находить именованный класс в пределах пакета; например, исходный код для a public ввести wet.sprocket.Toad был бы найден в файле Toad.java в каталоге wet/sprocket, и соответствующий объектный код был бы найден в файле Toad.class в том же самом каталоге.

Когда пакеты сохранены в базе данных (§7.2.2), хост-система не должна ввести такие ограничения.

Практически, много программистов хотят помещать каждый класс, или интерфейс вводят его собственную единицу компиляции, является ли это public или упоминается кодом в других единицах компиляции. Ошибка времени компиляции происходит, если имя высокоуровневого типа появляется как имя какого-либо другого высокоуровневого класса или интерфейсного типа, объявленного в том же самом пакете (§7.6).

Ошибка времени компиляции происходит, если имя высокоуровневого типа также объявляется как тип объявлением единственного импорта типа (§7.5.1) в единице компиляции (§7.3) содержащий описание типа.

В примере:

class Point { int x, y; }
Точка класса объявляется в единице компиляции без оператора пакета, и таким образом Точка является своим полностью определенным именем, тогда как в примере:

package vista;
class Point { int x, y; }
полностью определенное имя Точки класса vista.Point. (Перспектива имени пакета является подходящей для локального или персонального использования; если бы пакет был предназначен, чтобы быть широко распределенным, то было бы лучше дать этому уникальное имя пакета (§7.7).)

В примере:

package test;
import java.util.Vector;
class Point {
	int x, y;
}
interface Point {			// compile-time error #1
	int getR();
	int getTheta();
}
class Vector { Point[] pts; }		// compile-time error #2
первая ошибка времени компиляции вызывается двойным объявлением Точки имени и как класс и как interface в том же самом пакете. Вторая ошибка, обнаруженная во время компиляции, является попыткой объявить Вектор имени и объявлением типа класса и объявлением единственного импорта типа.

Отметьте, однако, что это не ошибка для имени класса также, чтобы назвать тип, который иначе мог бы быть импортирован объявлением "импорт типа по требованию" (§7.5.2) в единице компиляции (§7.3) содержащий объявление класса. В примере:

package test;
import java.util.*;
class Vector { Point[] pts; }		// not a compile-time error
объявление Вектора класса разрешается даже при том, что есть также класс java.util. Вектор. В пределах этой единицы компиляции простой Вектор имени обращается к тесту класса. Вектор, не к java.util. Вектор (который может все еще быть упомянут кодом в пределах единицы компиляции, но только ее полностью определенным именем).

Как другой пример, единица компиляции:

package points;
class Point {
	int x, y;			// coordinates
	PointColor color;		// color of this point
	Point next;			// next point with this color
	static int nPoints;
}
class PointColor {
	Point first;			// first point with this color
	PointColor(int color) {
		this.color = color;
	}
	private int color;		// color components
}
определяет два класса, которые используют друг друга в объявлениях их элементов класса. Поскольку у Точки типов классов и PointColor есть все описания типа в точках пакета, включая все те в текущей единице компиляции, как их контекст, этот пример компиляции правильно - то есть, ссылка вперед не является проблемой.

Это - ошибка времени компиляции, если высокоуровневое описание типа содержит кого-либо из следующих модификаторов доступа: защищенный, частный или статичный.

7.7 Уникальные Имена Пакета

Разработчики должны предпринять шаги, чтобы избежать возможности двух опубликованных пакетов, имеющих то же самое имя, выбирая уникальные имена пакета для пакетов, которые широко распределяются. Это позволяет пакетам быть легко и автоматически установленными и каталогизироваться. Этот раздел определяет предложенное соглашение для того, чтобы генерировать такие уникальные имена пакета. Реализации платформы Java поощряются оказать автоматическую поддержку для того, чтобы преобразовать ряд пакетов от локальных и случайных имен пакета до формата уникального имени, описанного здесь.

Если уникальные имена пакета не используются, то конфликты имен пакета могут возникнуть далекие от точки создания любого из конфликтных пакетов. Это может создать ситуацию, которая является трудной или невозможной для пользователя или программиста решить. Класс ClassLoader может использоваться, чтобы изолировать пакеты с тем же самым именем друг от друга в тех случаях, где пакеты ограничат взаимодействия, но не в пути, который прозрачен к наивной программе.

Вы формируете уникальное имя пакета, сначала имея (или принадлежа организации, которая имеет), имя Интернет-домена, такой как sun.com. Вы тогда инвертируете это имя, компонент компонентом, чтобы получить, в этом примере, com.sun, и используйте это, как префикс для Вашего пакета называет, используя соглашение разработанный в пределах Вашей организации, чтобы далее администрировать имена пакета.

В некоторых случаях имя интернет-домена, возможно, не допустимое имя пакета. Вот некоторые предложенные соглашения для того, чтобы иметь дело с этими ситуациями:

Такое соглашение могло бы определить, что определенные компоненты имени каталога были подразделением, отделом, проектом, машиной, или именами для входа в систему. Некоторые возможные примеры:
com.sun.sunsoft.DOE
com.sun.java.jag.scrabble
com.apple.quicktime.v2
edu.cmu.cs.bovik.cheese
gov.whitehouse.socks.mousefinder
Первый компонент уникального имени пакета всегда пишется во все-строчных буквах ASCII и должен быть одним из высокоуровневых доменных имен в настоящий момент com, edu, gov, mil, net, org, или один из английских двухбуквенных кодов, идентифицирующих страны как определено в Стандарте ISO 3166, 1981. Для получения дополнительной информации сошлитесь на документы, хранившие в ftp://rs.internic.net/rfc, например, rfc920.txt и rfc1032.txt.

Имя пакета не предназначается, чтобы подразумевать, где пакет сохранен в пределах Интернета; например, пакет называют edu.cmu.cs.bovik.cheese не обязательно доступно от Интернет-адреса cmu.edu или от cs.cmu.edu или от bovik.cs.cmu.edu. Предложенное соглашение для того, чтобы генерировать уникальные имена пакета является просто способом перевезти по железной дороге соглашение о присвоении имен пакета сверху существующего, широко известного реестра уникального имени вместо того, чтобы иметь необходимость создать отдельный реестр для имен пакета.


Содержание | Предыдущий | Следующий | Индекс Спецификация языка Java
Второй Выпуск
Авторское право © Sun Microsystems, Inc 2000 года. Все права защищены
Пожалуйста, отправьте любые комментарии или исправления к jls@java.sun.com