Spec-Zone.ru › Java Language Specification 8

Глава 7. Пакеты

Содержание

7.1. Члены пакета
7.2. Поддержка пакетов хостом
7.3. Единицы компиляции
7.4. Объявления пакетов
7.4.1. Имянные пакеты
7.4.2. Безымянные пакеты
7.4.3. Наблюдаемость пакета
7.5. Объявления импорта
7.5.1. Объявления импорта одного типа
7.5.2. Объявления импорта по умолчанию
7.5.3. Объявления импорта одного статического члена
7.5.4. Объявления импорта статических членов по умолчанию
7.6. Объявления типов верхнего уровня

Программы организованы как наборы пакетов. Каждый пакет имеет свой собственный набор имён для типов, что помогает предотвратить конфликты имён.

Тип верхнего уровня доступен (§6.6) за пределами пакета, в котором он объявлен, только если тип объявлен public.

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

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

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

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

7.1. Члены пакета

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

Например, в API платформы Java SE:

  • Пакет java имеет подпакеты awt, applet, io, lang, net и util, но не содержит единиц компиляции.

  • Пакет java.awt имеет подпакет с именем image, а также ряд единиц компиляции, содержащих объявления типов классов и интерфейсов.

Если полное имя (§6.7) пакета — P, и Q является подпакетом P, то P.Q — полное имя подпакета и, более того, обозначает пакет.

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

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

  • Поскольку пакет java.awt имеет подпакет image, он не может (и не содержит) объявление класса или типа интерфейса с именем image.

  • Если существует пакет с именем mouse и член типа Button в этом пакете (который затем может упоминаться как mouse.Button), то не может быть никакого пакета с полным именем mouse.Button или mouse.Button.Click.

  • Если com.nighthacks.java.jag — полное имя типа, то не может быть никакого пакета, чьё полное имя — com.nighthacks.java.jag или com.nighthacks.java.jag.scrabble.

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


package vector;
public class Vector { Object[] vec; }

который содержит класс public с именем Vector, даже если пакет java.util также объявляет класс с именем Vector. Эти два типа классов разные, что отражено в том, что у них разные полные имена (§6.7). Полное имя этого примера Vector — vector.Vector, а java.util.Vector — полное имя класса Vector, включённого в платформу Java SE. Поскольку пакет vector содержит класс с именем Vector, он не может также иметь подпакет с именем Vector.

Иерархическая структура именования пакетов предназначена для удобной организации связанных пакетов в соответствии с конвенциями, но не имеет никакого значения, кроме запрета на наличие подпакета в пакете с тем же простым именем, что и тип верхнего уровня (§7.6), объявленного в этом пакете.

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

7.2. Поддержка пакетов хост-системой

Каждая хост-система определяет, как создаются и хранятся пакеты и единицы компиляции.

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

В простых реализациях платформы Java SE пакеты и единицы компиляции могут храниться в локальной файловой системе. Другие реализации могут хранить их с использованием распределенной файловой системы или какой-либо базы данных.

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

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

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

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

Каталог может содержать следующие непосредственные подкаталоги:

com
gls
jag
java
wnj

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

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

applet
awt
io
lang
net
util

соответствующие пакетам java.applet, java.awt, java.io, java.lang, java.net и java.util, которые определены как часть API платформы Java SE.

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

BitSet.java        Observable.java
BitSet.class       Observable.class
Date.java          Observer.java
Date.class         Observer.class
...

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

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

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

jag.scrabble.board

преобразуется в имя каталога:

jag/scrabble/board

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

Согласно этому соглашению, имя пакета:

children.activities.crafts.papierM\u00e2ch\u00e9

которое также можно записать с использованием полного Unicode как:

children.activities.crafts.papierMâché

может быть отображено в имя каталога:

children/activities/crafts/papierM@00e2ch@00e9

Если символ @ не является допустимым символом в имени файла для какой-либо данной хост-файловой системы, то вместо него может использоваться какой-либо другой символ, который не является допустимым в идентификаторе.

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

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

CompilationUnit:
[PackageDeclaration] {ImportDeclaration} {TypeDeclaration}

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

  • Объявление пакета (§7.4), задающее полное квалифицированное имя (§6.7) пакета, к которому относится единица компиляции.

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

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

  • Объявления типов верхнего уровня (§7.6) классов и интерфейсов.

Каждая единица компиляции неявно импортирует все имена типов, объявленные в предопределённом пакете public, как если бы объявление import java.lang.*; появилось в начале каждой единицы компиляции сразу после любой инструкции package. В результате имена всех этих типов доступны как простые имена в каждой единице компиляции.

Все единицы компиляции предопределённого пакета java и его подпакетов lang и io всегда наблюдаемы.

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

Наблюдаемость единицы компиляции влияет на наблюдаемость её пакета (§7.4.3).

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

END_OF_DOCUMENT_MARKER

7.4. Декларации пакетов

Декларация package появляется внутри единицы компиляции, чтобы указать пакет, к которому принадлежит единица компиляции.

7.4.1. Именованные пакеты

Декларация пакета в единице компиляции задаёт имя (§6.2) пакета, к которому принадлежит единица компиляции.

PackageDeclaration:
{Модификатор пакета} package Идентификатор {. Идентификатор} ;
PackageModifier:
Аннотация

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

Область действия и перекрытие декларации пакета указаны в §6.3 и §6.4.

Правила для модификаторов аннотаций в декларации пакета указаны в §9.7.4 и §9.7.5.

Допускается не более одной аннотированной декларации package для данного пакета.

Способ, которым это ограничение обеспечивается, обязательно должен варьироваться от реализации к реализации. Следующая схема очень рекомендуется для реализаций, основанных на файловой системе: единственная аннотированная декларация package, если она существует, помещается в исходный файл, называемый package-info.java, в каталоге, содержащем исходные файлы пакета. Этот файл не содержит исходный код класса, называемого package-info.java; на самом деле это было бы незаконно, так как package-info не является допустимым идентификатором. Обычно package-info.java содержит только декларацию package, непосредственно перед которой указаны аннотации пакета. Хотя файл технически может содержать исходный код одного или нескольких классов с доступом к пакету, это было бы очень плохой практикой.

Рекомендуется, чтобы package-info.java, если он есть, заменил package.html для javadoc и других аналогичных систем генерации документации. Если этот файл присутствует, инструмент генерации документации должен искать комментарий документации пакета, непосредственно предшествующий (возможно, аннотированной) декларации package в package-info.java. Таким образом, package-info.java становится единственным хранилищем аннотаций и документации уровня пакета. Если в будущем возникнет необходимость добавить другую информацию уровня пакета, этот файл окажется удобным хранилищем для этой информации.

7.4.2. Пакеты без имени

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

Пакеты без имени предоставляются платформой Java SE в основном для удобства при разработке небольших или временных приложений или при только что начатой разработке.

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

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

Пример 7.4.2-1.

Единица компиляции:

class FirstCall {
    public static void main(String[] args) {
        System.out.println("Mr. Watson, come here. "
                           + "I want you.");
    }
}

определяет очень простую единицу компиляции как часть пакета без имени.


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

7.4.3. Наблюдаемость пакета

Пакет наблюдаем, если и только если:

  • Единица компиляции, содержащая объявление пакета, наблюдаема (§7.3).

  • Подпакет пакета наблюдаем.

Пакеты java, java.lang и java.io всегда наблюдаемы.

Это можно заключить из правила выше и из правил наблюдаемых единиц компиляции, как следует. Предварительно определённый пакет java.lang объявляет класс Object, поэтому единица компиляции для Object всегда наблюдаема (§7.3). Следовательно, пакет java.lang наблюдаем (§7.4.3), и также пакет java. Кроме того, так как Object наблюдаем, тип массива Object[] неявно существует. Его суперинтерфейс java.io.Serializable (§10.1) также существует, следовательно, пакет java.io наблюдаем.

7.5. Декларации импорта

Декларация импорта позволяет ссылаться на именованный тип или член static по простому имени (§6.2), состоящему из одного идентификатора.

Без соответствующей декларации импорта единственный способ ссылки на тип, объявленный в другом пакете, или на static член другого типа, — использование полных квалифицированных имен (§6.7).

ImportDeclaration:
SingleTypeImportDeclaration
TypeImportOnDemandDeclaration
SingleStaticImportDeclaration
StaticImportOnDemandDeclaration
  • Декларация импорта одного типа (§7.5.1) импортирует один именованный тип, указав его каноническое имя (§6.7).

  • Декларация импорта всех типов (§7.5.2) импортирует все доступные типы (§6.6) именованного типа или именованного пакета по мере необходимости, указав каноническое имя типа или пакета.

  • Декларация импорта одного статического члена (§7.5.3) импортирует все доступные static члены с заданным именем из типа, указав его каноническое имя.

  • Декларация импорта всех статических членов (§7.5.4) импортирует все доступные static члены именованного типа по мере необходимости, указав каноническое имя типа.

Область действия и перекрытие типа или члена, импортированного этими декларациями, определены в §6.3 и §6.4.

Декларация import делает типы или члены доступными по их простым именам только в единице компиляции, которая фактически содержит декларацию import. Область действия введенных типом(ами) или членом(ами) декларацией import конкретно не включает другие единицы компиляции в том же пакете, другие декларации import в текущей единице компиляции или декларацию package в текущей единице компиляции (за исключением аннотаций декларации package).

7.5.1. Декларации импорта одного типа

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

SingleTypeImportDeclaration:
import TypeName ;

Тип TypeName должен быть каноническим именем типа класса, типа интерфейса, типа перечисления или типа аннотации (§6.7).

Имя должно быть квалифицированным (§6.5.5.2), в противном случае произойдет ошибка компиляции.

Ошибка компиляции возникает, если указанный тип недоступен (§6.6).

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

Если тип, импортированный декларацией импорта одного типа, объявлен в единице компиляции, содержащей декларацию import, то декларация import игнорируется.

Если единица компиляции содержит декларацию импорта одного типа, импортирующую тип с простым именем n, и декларацию импорта одного статического члена (§7.5.3), импортирующую тип с простым именем n, возникает ошибка компиляции.

Пример 7.5.1-1. Импорт одного типа


import java.util.Vector;

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

Обратите внимание, что фактическая декларация java.util.Vector является обобщённой (§8.1.2). После импорта имя Vector может использоваться без квалификации в параметризованном типе, например, Vector<String>, или как тип без параметров Vector. Ограничение, связанное с декларацией import, заключается в том, что вложенный тип, объявленный внутри декларации обобщённого типа, может быть импортирован, но его внешний тип всегда стирается.


Пример 7.5.1-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; }


Пример 7.5.1-3. Отсутствие импорта подпакета

Обратите внимание, что оператор import не может импортировать подпакет, только тип.

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


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


Пример 7.5.1-4. Импорт имени типа, которое также является именем пакета

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

package Vector;
public class Mosquito { int capacity; }

а затем единица компиляции:

package strange;
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());
    }
}

декларация импорта класса Vector из пакета java.util не предотвращает появление и правильное распознавание имени пакета Vector в последующих декларациях import. Пример компилируется и выводит:

class java.util.Vector
class Vector.Mosquito

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

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

TypeImportOnDemandDeclaration:
import ИмяПакетИлиТип . * ;

Имя PackageOrTypeName должно быть каноническим именем (§6.7) пакета, класса, интерфейса, перечисления или аннотации.

Если PackageOrTypeName обозначает тип (§6.5.4), то имя должно быть квалифицированным (§6.5.5.2), иначе произойдёт ошибка компиляции.

Ошибка компиляции возникает, если указанный пакет или тип недоступен (§6.6).

Ошибка компиляции не возникает, если в объявлении импорта типа по требованию указан либо java.lang, либо имя пакета текущей единицы компиляции. В таких случаях объявление импорта типа по требованию игнорируется.

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

Если единица компиляции содержит как объявление импорта типа по требованию, так и объявление статического импорта по требованию (§7.5.4), указывающие на один и тот же тип, то эффект такой, как будто члены типа (§8.5, §9.5) импортированы только один раз.

Пример 7.5.2-1. Импорт типа по требованию


import java.util.*;

приводит к тому, что простые имена всех public типов, объявленных в пакете java.util, становятся доступными внутри объявлений классов и интерфейсов единицы компиляции. Таким образом, простое имя Vector ссылается на тип Vector в пакете java.util во всех местах единицы компиляции, где это объявление типа не затенено (§6.4.1) или скрыто (§6.4.2).

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

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

(Такие условия встречаются редко.)


7.5.3. Объявления импорта одного статического элемента

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

SingleStaticImportDeclaration:
import static ИмяТипа . Идентификатор ;

Имя TypeName должно быть каноническим именем (§6.7) класса, интерфейса, перечисления или аннотации.

Имя должно быть квалифицированным (§6.5.5.2), иначе произойдёт ошибка компиляции.

Ошибка компиляции возникает, если указанный тип недоступен (§6.6).

Идентификатор Identifier должен обозначать по крайней мере один static член указанного типа. Ошибка компиляции возникает, если члена с таким именем нет или если все именованные члены недоступны.

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

Если объявление импорта одного статического элемента импортирует тип с простым именем n, а единица компиляции также объявляет тип верхнего уровня (§7.6) с простым именем n, возникает ошибка компиляции.

Если единица компиляции содержит как объявление импорта одного статического элемента, импортирующего тип с простым именем n, так и объявление импорта одного типа (§7.5.1), импортирующего тип с простым именем n, возникает ошибка компиляции.

7.5.4. Объявления статического импорта по требованию

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

StaticImportOnDemandDeclaration:
import static ИмяТипа . * ;

Имя TypeName должно быть каноническим именем (§6.7) класса, интерфейса, перечисления или аннотации.

Имя должно быть квалифицированным (§6.5.5.2), иначе произойдёт ошибка компиляции.

Ошибка компиляции возникает, если указанный тип недоступен (§6.6).

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

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

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

Если единица компиляции содержит объявление статического импорта по требованию и объявление импорта типа по требованию (§7.5.2), указывающие на один и тот же тип, то эффект такой, как будто члены-типы этого типа (§8.5, §9.5) импортированы только один раз.

7.6. Объявления типов верхнего уровня

Объявление типа верхнего уровня объявляет тип верхнего уровня класса (§8 (Классы)) или тип верхнего уровня интерфейса (§9 (Интерфейсы)).

TypeDeclaration:
ClassDeclaration
InterfaceDeclaration
;

Дополнительные ";" токены, появляющиеся на уровне объявлений типов в единице компиляции, не влияют на значение единицы компиляции. В языке программирования Java допускаются лишние точки с запятой исключительно как уступка программистам C++, привыкшим к добавлению ";" после объявления класса. Их не следует использовать в новом коде Java.

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

Ошибка времени компиляции, если объявление типа верхнего уровня содержит один из следующих модификаторов доступа: protected, private или static.

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

Область видимости и перекрытие типа верхнего уровня указаны в §6.3 и §6.4.

Полное квалифицированное имя типа верхнего уровня указано в §6.7.

Пример 7.6-1. Конфликтующие объявления типов верхнего уровня

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

Здесь первая ошибка времени компиляции вызвана дублированием объявления имени Point как класса, так и интерфейса в одном пакете. Вторая ошибка времени компиляции — попытка объявить имя Vector как объявлением типа класса, так и объявлением импорта типа.

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

package test;
import java.util.*;
class Vector {}  // not a compile-time error

объявление класса Vector разрешено, даже если есть также класс java.util.Vector. Внутри этой единицы компиляции простое имя Vector относится к классу test.Vector, а не к java.util.Vector (к которому можно обратиться в коде внутри единицы компиляции, но только по полному квалифицированному имени).


Пример 7.6-2. Область видимости типов верхнего уровня

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
}

Эта программа определяет два класса, которые используют друг друга в объявлениях своих членов класса. Поскольку все объявления типов классов Point и PointColor находятся в пакете points, включая все объявления в текущей единице компиляции, их область видимости, эта программа компилируется без ошибок. То есть, ссылка вперёд не является проблемой.


Пример 7.6-3. Полные квалифицированные имена


class Point { int x, y; }

В этом коде класс Point объявлен в единице компиляции без инструкции package, и поэтому Point является его полным квалифицированным именем, тогда как в коде:


package vista;
class Point { int x, y; }

полное квалифицированное имя класса Point является vista.Point. (Имя пакета vista подходит для локального или личного использования; если пакет предназначен для широкого распространения, лучше использовать уникальное имя пакета (§6.1).)


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

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


import java.util.Vector;

тогда в рамках этой единицы компиляции простое имя Vector и полное квалифицированное имя java.util.Vector ссылаются на один и тот же тип.

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

  • К типу обращается код в других единицах компиляции пакета, в котором тип объявлен.

  • Тип объявлен public (и, следовательно, потенциально доступен из кода в других пакетах).

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

Например, исходный код для типа public wet.sprocket.Toad будет найден в файле Toad.java в каталоге wet/sprocket, а соответствующий объектный код будет найден в файле Toad.class в том же каталоге.

© Oracle and/or its affiliates. All rights reserved.
Licensed under the Oracle Technology Network License Agreement.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API