Почему плохо использовать подстановочный знак с оператором импорта Java? - PullRequest
354 голосов
/ 29 сентября 2008

Гораздо удобнее и понятнее использовать одно выражение типа

import java.awt.*;

чем импортировать кучу отдельных классов

import java.awt.Panel;
import java.awt.Graphics;
import java.awt.Canvas;
...

Что не так с использованием подстановочного знака в операторе import?

Ответы [ 14 ]

435 голосов
/ 29 сентября 2008

Единственная проблема в том, что он загромождает ваше локальное пространство имен. Например, предположим, что вы пишете приложение на Swing, и вам нужно java.awt.Event, а также вы взаимодействуете с системой календаря компании, которая имеет com.mycompany.calendar.Event. Если вы импортируете оба метода подстановки, произойдет одно из следующих трех событий:

  1. У вас прямой конфликт имен между java.awt.Event и com.mycompany.calendar.Event, поэтому вы даже не можете скомпилировать.
  2. На самом деле вам удается импортировать только один (только один из двух ваших импортов делает .*), но это неверный вариант, и вы изо всех сил пытаетесь выяснить, почему ваш код утверждает, что тип неправильный.
  3. Когда вы компилируете свой код, com.mycompany.calendar.Event нет, но когда они позже добавят один, ваш ранее действительный код внезапно прекращает компиляцию.

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

167 голосов
/ 29 сентября 2008

Вот голос за звездный импорт. Оператор import предназначен для импорта пакета , а не класса. Гораздо чище импортировать целые пакеты; проблемы, выявленные здесь (например, java.sql.Date против java.util.Date), легко устраняются другими средствами, а не действительно , решаемыми определенным импортом, и, конечно, не оправдывают безумно педантичный импорт всех классов. Нет ничего более смущающего, чем открытие исходного файла и необходимость пролистать 100 операторов импорта.

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

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

Вот как бороться с конфликтами классов:

import java.sql.*;
import java.util.*;
import java.sql.Date;
150 голосов
/ 29 сентября 2008

см. Мою статью Импорт по требованию - зло

Короче говоря, самая большая проблема в том, что ваш код может сломаться, когда класс добавляет в пакет, который вы импортируете. Например:

import java.awt.*;
import java.util.*;

// ...

List list;

В Java 1.1 это было нормально; Список был найден в java.awt, конфликта не было.

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

Java 1.2 добавил интерфейс с именем List в java.util. БУМ! Конфликт. Отлично работающий код больше не работает.

Это языковая функция ЗЛО . Существует NO причина, по которой код должен перестать компилироваться только потому, что тип добавлен в пакет ...

Кроме того, читателю трудно определить, какой «Foo» вы используете.

63 голосов
/ 02 января 2010

Это не плохо использовать подстановочный знак с оператором импорта Java.

В Чистый код Роберт Мартин рекомендует использовать их, чтобы избежать длинных списков импорта.

Вот рекомендация:

J1: избегайте длинных списков импорта с помощью Wildcards

Если вы используете два или более классов из пакет, а затем импортировать весь пакет с

Импортная упаковка. *;

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

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

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

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

22 голосов
/ 29 сентября 2008

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

import java.util.*;
import java.awt.*;

...
List blah; // Ambiguous, needs to be qualified.

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

20 голосов
/ 06 мая 2014

Производительность : Не влияет на производительность, так как байт-код одинаков. хотя это приведет к некоторым издержкам компиляции.

Компиляция : на моем персональном компьютере компиляция пустого класса без импорта чего-либо занимает 100 мс, но тот же класс при импорте java. * Занимает 170 мс.

14 голосов
/ 29 сентября 2008
  1. Это помогает идентифицировать конфликты имен классов: два класса в разных пакетах с одинаковыми именами. Это может быть замаскировано с помощью * import.
  2. Это делает зависимости явными, так что каждый, кто будет читать ваш код позже, знает, что вы хотели импортировать и что вы не хотели импортировать.
  3. Это может ускорить компиляцию, потому что компилятору не нужно искать весь пакет для выявления зависимостей, хотя обычно это не так уж сложно для современных компиляторов.
  4. Неудобные аспекты явного импорта сводятся к минимуму с помощью современных сред IDE. Большинство IDE позволяют свернуть раздел импорта, чтобы он не мешал, автоматически заполняет импорт при необходимости и автоматически определяет неиспользуемый импорт, чтобы помочь очистить его.

В большинстве мест, где я работал, где используется сколько-нибудь значительное количество Java, явный импорт является частью стандарта кодирования. Иногда я все еще использую * для быстрого создания прототипов, а затем расширяю списки импорта (некоторые IDE будут делать это и для вас) при создании кода.

10 голосов
/ 29 сентября 2008

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

9 голосов
/ 10 октября 2008

В предыдущем проекте я обнаружил, что переход от * -импортов к конкретным импортам сокращает время компиляции вдвое (с 10 минут до 5 минут). * -Import заставляет компилятор искать в каждом из перечисленных пакетов класс, соответствующий тому, который вы использовали. Хотя это время может быть небольшим, оно складывается для больших проектов.

Побочным эффектом * -импорта было то, что разработчики копировали и вставляли общие строки импорта, а не думали о том, что им нужно.

6 голосов
/ 17 июня 2016

In DDD book

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

И если он загромождает локальное пространство имен, это не ваша вина - вините в размере пакета.

...