Содержание | Предыдущий | Следующий | Индекс

ГЛАВА 7

Пакеты


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

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

Пакет может быть сохранен в файловой системе (§7.2.1) или в базе данных (§7.2.2). У пакетов, которые сохранены в файловой системе, есть определенные ограничения на организацию их единиц компиляции, чтобы позволить простой реализации находить классы легко. В любом случае набор пакетов, доступных программе Java, определяется хост-системой, но должен всегда включать, по крайней мере, три стандартных пакета java.lang, java.util, и java.io как определено в Главах 20, 21, и 22. В большинстве сред узла, стандартных пакетах java.applet, java.awt, и java.net, которые не описываются в этой спецификации, также доступны программам Java.

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

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

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

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

У пакета могут быть элементы или или оба из следующих видов:

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

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

Подпакеты пакета java именованный lang, util, и io (чьи полностью определенные имена пакета поэтому java.lang, java.util, и java.io) стандартный компонент каждой реализации Java и определяется в Главах 20, 21, и 22. Много реализаций Java будут включать весь набор java пакеты, определенные в ряде книг Прикладной программный интерфейс Java.

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

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

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

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

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

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

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


COM
gls
jag
java
wnj
где каталог java содержал бы стандартные пакеты Прикладного программного интерфейса 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
Dictionary.java										Properties.java
Dictionary.class										Properties.class
EmptyStackException.java										Random.java
EmptyStackException.class										Random.class
Enumeration.java										Stack.java
Enumeration.class										Stack.class
Hashtable.java										StringTokenizer.java
Hashtable.class										StringTokenizer.class
NoSuchElementException.java										Vector.java
NoSuchElementException.class										Vector.class
где каждый из .java файлы содержат источник для единицы компиляции (§7.3), который содержит определение класса или интерфейса, двоичный файл которого скомпилированная форма содержится в соответствии .class файл.

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

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

jag/scrabble/board
и:

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

COM/Sun/sunsoft/DOE
Фактически, стандартный Набор Разработчика Java JavaSoft на UNIX отличается от очень простой дисциплины, описанной здесь только, в котором это обеспечивает a CLASSPATH переменная окружения, которая определяет ряд каталогов, каждый из которых обрабатывается как единственный каталог, описанный здесь. Эти каталоги ищутся для определений именованных пакетов и типов.

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

children.activities.crafts.papierM\u00e2ch\u00e9
который может также быть записан, используя полный Unicode как:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Если тип по имени T объявляется в единице компиляции пакета, полностью определенное имя которого является P, то полностью определенное имя типа является P.T; таким образом в примере:

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

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

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


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

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

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

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

Предостережение должно быть взято при использовании неназванных пакетов. Для единицы компиляции в именованном пакете возможно импортировать тип из неназванного пакета, но скомпилированная версия этой единицы компиляции будет, вероятно, тогда работать только, когда тот определенный неназванный пакет будет "текущим". Поэтому строго рекомендуется, чтобы единицы компиляции именованных пакетов никогда не импортировали типы из неназванных пакетов. Также рекомендуется, чтобы любой тип, объявленный в неназванном пакете не, был объявлен public, сохранить их от того, чтобы случайно быть импортированным именованным пакетом.

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

7.4.3 Контекст и Сокрытие Имени Пакета

Какие высокоуровневые имена пакета находятся в контексте (§6.3, §6.5) определяется соглашениями хост-системы.

Имена пакета никогда не скрывают другие имена.

7.4.4 Доступ к Элементам Пакета

Предоставляется ли доступ к элементам пакета, определяется хост-системой. Пакет java должно всегда быть доступным, и его стандартные подпакеты lang, io, и util должно всегда быть доступным.

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

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

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

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

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

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

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

TypeName должен быть полностью определенным именем класса или интерфейсного типа; ошибка времени компиляции происходит, если именованный тип не существует. Если именованный тип не находится в текущем пакете, то это должно быть доступно (§6.6) - в доступном пакете и объявленный public (§8.1.2, §9.1.2) - или ошибка времени компиляции происходит.

Пример:

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

Если два объявления единственного импорта типа в той же самой единице компиляции пытаются импортировать типы с тем же самым простым именем, то ошибка времени компиляции происходит, если два типа не являются тем же самым типом, когда двойное объявление игнорируется. Если другой тип с тем же самым именем иначе объявляется в текущей единице компиляции кроме объявлением "импорт типа по требованию" (§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; }
Компилятор отслеживает типы их полностью определенными именами (§6.7). Простые имена и полностью определенные имена могут использоваться взаимозаменяемо всякий раз, когда они оба доступны.

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


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

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

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

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

Пример:

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

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

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

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

Полная спецификация java.lang дается в Главе 20. Следующий public типы определяются в java.lang:


AbstractMethodError										LinkageError
ArithmeticException										Long
ArrayStoreException										Math
Boolean										NegativeArraySizeException
Character										NoClassDefFoundError
Class										NoSuchFieldError
ClassCastException										NoSuchMethodError
ClassCircularityError										NullPointerException
ClassFormatError										Number
ClassLoader										NumberFormatException
ClassNotFoundException										Object
CloneNotSupportedException										OutOfMemoryError
Cloneable										Process
Compiler										Runnable
Double										Runtime
Error										RuntimeException
Exception										SecurityException
ExceptionInInitializerError										SecurityManager
Float										StackOverflowError
IllegalAccessError										String
IllegalAccessException										StringBuffer
IllegalArgumentException										System
IllegalMonitorStateException										Thread
IllegalThreadStateException										ThreadDeath
IncompatibleClassChangeError										ThreadGroup
IndexOutOfBoundsException										Throwable
InstantiationError										UnknownError
InstantiationException										UnsatisfiedLinkError
Integer										VerifyError
InternalError										VirtualMachineError
InterruptedException

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):

Компилятор Java должен проигнорировать дополнительный";"маркеры, появляющиеся на уровне описаний типа. Беспризорные точки с запятой разрешаются в Java исключительно как концессия программистам на C++, которые привыкли писать:

class date { int month, day, year; };
(В C++, но не в Java, можно обеспечить список разделенных запятой значений идентификаторов, чтобы объявить переменные между"}"и";".) Дополнительные точки с запятой не должны использоваться в новом коде Java. Программное обеспечение, которое переформатировало код Java, может удалить их.

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

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

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

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

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

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

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

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

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

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

Вы формируете уникальное имя пакета, сначала имея (или принадлежа организации, которая имеет), имя Интернет-домена, такой как 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 для того, чтобы генерировать уникальные имена пакета является просто способом перевезти по железной дороге соглашение о присвоении имен пакета сверху существующего, широко известного реестра уникального имени вместо того, чтобы иметь необходимость создать отдельный реестр для имен пакета Java.

Если Вы должны получить новое имя Интернет-домена, можно получить анкету от ftp://ftp.internic.net и представьте полные формы по Электронной почте к domreg@internic.net. Чтобы узнать, каковы в настоящий момент зарегистрированные доменные имена, Вы можете telnet к rs.internic.net и используйте whois средство.


Содержание | Предыдущий | Следующий | Индекс

Спецификация языка Java (HTML, сгенерированный Блинчиком "сюзет" Pelouch 24 февраля 1998)
Авторское право © Sun Microsystems, Inc 1996 года. Все права защищены
Пожалуйста, отправьте любые комментарии или исправления к doug.kramer@sun.com



Spec-Zone.ru - all specs in one place



free hit counter