Главная » Java » Пакеты Java и проблема конфликтов имен

0

При разработке программного кода, который, как предполагается, будет использоваться повторно, возникает проблема конфликтов имен. Совершенно неважно, насколько тщательно вы подошли к задаче выбора идентификаторов собственных классов, – возможно, кто-то еще из числа будущих пользователей вашего кода употребит аналогичные имена для других целей. Если вы применяете тривиальные, легко предсказуемые имена, проблема еще более усугубляется – те же идентификаторы почти наверняка будут использованы и другим программистом, который, как и вы, исповедует принцип просто ты и стремится обеспечить удобочитаемость собственного кода. Слова, подобные list (список), event (событие), component (компонент) и Т.Д., употребляются настолько часто, что их взаимное "пересечение" можно гарантировать с полной уверенностью.

Традиционное решение проблемы конфликтов имен во многих языках программирования состоит в использовании в идентификаторах классов (а также типов, глобальных функций и т.п.) префиксов, соответствующих именам пакетов. Такое соглашение позволяет создавать контексты имен, препятствующие возникновению подобных конфликтов. Префиксы обычно представляют собой аббревиатуры из нескольких символов, соответствующие наименованиям библиотек (примером может служить префикс Xt, отвечающий продукту X-Windows Toolkit).

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

Язык Java трактует понятие пакета в виде набора объявлений классов и соответствующих производных типов. Пакетам присваиваются имена. Предполагается, что пакеты могут быть импортированы. Имя пакета оформляется в Виде иерархии Наименований типов, разделенных символом точки. При обращении к объекту пакета в тексте программы необходимо задавать его полное имя, включая и префикс самого пакета, либо воспользоваться возможностью импорта всего пакета или требуемой его части. Инструкция импорта просто предписывает компилятору обращаться к указанному пакету за объявлениями типов, которые не описаны в тексте прикладной программы. Задавая имена пакетов, вы препятствуете Возникновению конфликтов имен. Если два пакета содержат объявления классов с одним и тем же именем, вам достаточно полностью задать имя хотя бы одного из них.

Ниже приведен текст примера, в котором создается объект класса Date стандартного пакета uti1, позволяющий получить системные дату и время. При обращении к классу указывается его полное имя. Как и во всех других классах, оперирующих временными данными, время отсчитывается в миллисекундах, начиная с 00:00:00 часов 1 января 1970 года по Гринвичу.

class Date1 {

public static void main(string[] args) {

java.util.Date now = new java.util.Date();

System.out.println(now);

}

}

 

А теперь рассмотрим другую версию примера, в которой предусмотрена инструкция предварительного импорта класса Date:

import java.util.Date;

class Date2 {

public static void main(String[] args) {

Date now = new Date();

 System.out.println(now);

}

}

Когда компилятор, анализируя текст программы, встречает объявление объекта now, он воспринимает Date именно как тип Java.util.Date, Поскольку последний – это единственный из всех мыслимых типов Date, Который в данном Случае известен компилятору. Инструкция импорта просто предоставляет компилятору дополнительные сведения и никоим образом не означает, что в текущий файл будут "включены" какие-то дополнительные данные.

Строго говоря, соглашение, касающееся правил именования пакетов, все еще Окончательно не разрешает проблемы конфликтов идентификаторов. Два наудачу Взятых проекта вполне могут быть реализованы в виде пакетов с одинаковыми названиями. Поэтому соглашение требует развития. Уточненные рекомендации Выглядят так: следует предварять наименование пакета обратным доменным Intrnеt-адресом той организации, которая создала пакет. Например, если компания АВС Corporation обладает доменным именем abc. сот, при обращении к разработанным ею пакетам Java необходимо предварительно задавать строку соm.abc, как, скажем, в случае com.abc.tools.

Употребление в именах пакетов разделительного символа точки иногда способно при водить к недоразумениям, поскольку тот же символ применяется и при обращении к методам и полям объектов, заданных посредством ссылок. Подобный синтаксис в контексте инструкции не позволяет получить вполне точный ответ на вопрос, что именно может быть импортировано. Новички часто пытаются выполнить команду в надежде избежать неприятной повинности, связанной с вводом соответствующего префикса при каждом обращении к методу ргintln. Такой подход ошибочен, поскольку system – это класс, а out – статический объект в составе класса system, поддерживающий, в частности, и метод ргintln.

С другой стороны, java.util.Date – это класс, который может быть импортирован (часто в инструкции import применяют аргумент, подобный java. uti1 . *, если необходимо импортировать все содержимое указанного пакета). Если при попытке импорта вы сталкиваетесь с проблемой, убедитесь, что в качестве аргумента инструкции указан именно тип.

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

package com.sun.games;

class Card {

//…

}

Если объявление package явно не задано, предполагается, что класс служит частью анонимного пакета (unnamed package). Способ оформления кода в виде анонимного пакета вполне приемлем, если речь идет об исполняемом приложении (или аплете), которое заведомо не предназначено для вызова из какой бы то ни было сторонней программы. Тексты классов, которые ориентированы на совместное использование, должны быть размещены в именованных пакетах.

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

По теме:

  • Комментарии