2013-04-06 3 views
0

Стреперированные заявления о продаже:Зачем определять множественный импорт?

import java.io. *; // Смысл

импорт javax.servlet. *;

импорт javax.servlet.http. *;

Не так ли, что мы включили «импорт javax.servlet. ;» и поэтому он автоматически будет включать в себя и другой оператор импорта, который является «import javax.servlet.http.;»?

Почему «импорт javax.servlet.http. *» Явно определен для http?

Просьба уточнить и сообщить мне, если я ошибаюсь.

ответ

1

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

Почему? Что касается JLS, то «com.example» и «com.example.pkg» являются несвязанными пакетами. Понятие субпакета упоминается в JLS, но не существует связанной семантики.В частности, не в правилах доступа. JLS 7.1 говорит:

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

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

(И конструкция, которая позволяет импорт ряда несвязанных пакетов имеет плохие последствия ... см. Ниже)

Но почему? Потому что именно так разработан язык.

Но ПОЧЕМУ? Вам нужно будет спросить команду разработчиков языка Java, что они думали в начале 1990-х годов, когда принимались проектные решения.


Но, возможно, мы можем видеть, что произойдет, если есть WID-файл с несколькими пакетами.

Рассмотрим этот пакет структуру, которая является довольно распространенным узором:

com.example.weazellib - contains the public API classes for the library 
    com.example.weazellib.impl - contains implementation classes that 
           shouldn't be used by external clients 

Это хорошо известный факт, что программисты ленивы (OK много есть), поэтому некоторые программист может написать это:

import com.example.weazellib.** // hypothetical syntax 

Он/она будет теперь как внешние классы API и внутренние классы в этом пространстве имен классов, и это будет легко случайно создать зависимость от внутренностей.

(И прежде чем вы говорите «сделать внутренний пакет классов частным» ... что не работает. Есть классы com.example.weazellib, которые должны быть в состоянии использовать классы в com.example.weazellib.impl. Если последнем был пакет частным, то первый не сможет их использовать.)

В отличие от этого, в мире, где Java не имеет подстановочных знаков, которые импортируют «деревья», вы не можете сделать это случайно. Вы должны сознательно импортировать пакет impl. Это ХОРОШЕЕ ВЕЩАНИЕ, и гораздо важнее, чем «неудобство» написания подстановочных импортов для нескольких пакетов.


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

Предположим, что программист решил, что импорт как com.example.weazellib, так и com.example.weazellib.impl был правильной вещью в своем коде ... и использует супер-шаблон для импорта обоих. И предположим, что он пишет свой код для использования com.example.weazellib.impl.ToesImpl ... как ToesImpl.

Теперь рассмотрим, что произойдет, если разработчик «weazellib» добавит третий пакет com.example.weazellib.impl2, который содержит альтернативные классы реализации ... с теми же простыми именами, что и классы в impl; например теперь у нас есть классы, такие как:

com.example.weazellib.impl.ToesImpl 
com.example.weazellib.impl2.ToesImpl 

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

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

+0

Ну, это действительно имеет смысл, почему вы хотите импортировать все дерево «подпакетов», если вы не будете их использовать. –

+0

@kellax - Я не могу понять, что * вы говорите «имеет смысл». Текущая модель, или модель с «супер-подстановочным» импортом. Я хочу сказать, что ленивые программисты использовали бы супер-подстановочный знак, не думая ... «Потому что это меньше набирает или что-то в этом роде. (Так же, как они игнорировали бы обработку исключений, если бы Java не проверяла исключения.) И есть также проблемы с устойчивостью перед изменениями внутренних данных библиотеки. –

+0

Спасибо за ваши ответы ребята, но есть ли какой-либо официальный java-документ, который явно говорит, что подпакеты существуют, как упоминалось в @kellax? – Adarsh

1

Нет, когда вы импортируете что-либо, импортируемое только определенным классом, или импортируете пакет, а также все классы, принадлежащие этому пакету, но не классы, принадлежащие к подпакету этого пакета.

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

Пример:
Допустим, вы строите класс View для приложения GUI вы можете захотеть, чтобы отделить проблемы, так что вы бы JComponents на ваш взгляд, и ваш Listeners в контроллерах.

Так что в вашем View вы бы импортировать: import javax.swing.*; таким образом, вы получите все JComponent классы, но так как вам не нужно event пакет с вашей точки зрения это имеет смысл, что импорт импортирует только то, что вам действительно нужно. Даже пакет swing и event несколько связаны с тем, что нет необходимости импортировать событие.

Так что, когда вы импортируете что-то в Java вы либо импортировать весь пакет import javax.swing.*; Со всеми классами, которые касаются пакета или вы импортируете один класс пакета import javax.swing.JButton;

Вы никогда не импортировать пакет со всеми его подпакеты и их подпакеты и т. д. Как очень вероятно, что вам не нужны все они.

0

Определяется в спецификации, как работает импорт.

См Java Language Spec

Причина в том, javax.servlet и javax.servlet.http разные пакеты, а импорт * приносит только членам пакета.

Кроме того, это не очень хорошая идея для импорта дикой карты, поскольку она делает код менее читаемым.

Смежные вопросы