Ответы:
Единственная проблема в том, что он загромождает ваше локальное пространство имен. Например, предположим, что вы пишете приложение на Swing, и вам нужно java.awt.Event
, а также взаимодействует с системой календаря компании, которая имеет com.mycompany.calendar.Event
. Если вы импортируете оба метода подстановки, происходит одно из следующих трех событий:
java.awt.Event
и com.mycompany.calendar.Event
, поэтому вы даже не можете скомпилировать..*
), но это неправильный вариант, и вы изо всех сил пытаетесь выяснить, почему ваш код утверждает, что тип неправильный.com.mycompany.calendar.Event
, но когда он позже добавляется, ваш ранее действительный код внезапно прекращает компиляцию.Преимущество явного перечисления всех импортов состоит в том, что я могу сразу определить, какой класс вы намеревались использовать, что просто делает чтение кода намного проще. Если вы просто делаете быструю разовую вещь, в этом нет ничего явно неправильного , но будущие сопровождающие будут благодарить вас за вашу ясность в противном случае.
Вот голос за звездный импорт. Оператор импорта предназначен для импорта пакета , а не класса. Гораздо чище импортировать целые пакеты; выявленные здесь проблемы (например, java.sql.Date
vs java.util.Date
) легко устраняются другими средствами, которые на самом деле не решаются с помощью конкретного импорта и, конечно, не оправдывают безумно педантичный импорт для всех классов. Нет ничего более смущающего, чем открытие исходного файла и необходимость пролистать 100 операторов импорта.
Выполнение определенного импорта затрудняет рефакторинг; если вы удаляете / переименовываете класс, вам нужно удалить все его специфические импорта. Если вы переключаете реализацию на другой класс в том же пакете, вы должны исправить импорт. Несмотря на то, что эти дополнительные шаги могут быть автоматизированы, они действительно являются хитами производительности без реальной выгоды.
Даже если Eclipse не выполняет импорт классов по умолчанию, все равно будут выполнять импорт звездочек. Извините, но на самом деле нет рационального обоснования для выполнения конкретного импорта.
Вот как бороться с конфликтами классов:
import java.sql.*;
import java.util.*;
import java.sql.Date;
Foo
, и если я прочитал ваш код без использования IDE (поскольку вы утверждаете, что мне не нужно его использовать), как я узнаю, из какого пакета Foo
пришел ? Конечно, используя IDE, IDE скажет мне, но весь ваш аргумент в том, что я смогу прочитать код без такового. Выполнение явного импорта помогает документировать код (хорошая причина избегать подстановочных знаков) , и гораздо более вероятно, что я буду читать код без использования IDE, чем то, что я буду писать код без использования IDE.
пожалуйста, смотрите мою статью « Импорт по требованию - зло»
Короче говоря, самая большая проблема в том , что ваш код может сломаться , когда класс добавляется к пакету импортируемого. Например:
import java.awt.*;
import java.util.*;
// ...
List list;
В Java 1.1 это было нормально; Список был найден в java.awt и не было никакого конфликта.
Теперь предположим, что вы зарегистрировали свой отлично работающий код, а год спустя кто-то другой выдает его для редактирования и использует Java 1.2.
Java 1.2 добавила интерфейс с именем List в java.util. БУМ! Конфликт. Отлично работающий код больше не работает.
Это особенность злого языка. Там нет НИКАКОЙ причины того, что код должен прекратить сбор только потому тип добавляется в пакет ...
Кроме того, читателю трудно определить, какой «Foo» вы используете.
java.util.List
vs java.awt.List
не так уж плохо понять, но попробуйте, когда имя класса Configuration
и несколько библиотек зависимостей добавили его в свою последнюю версию репозитория Maven.
Это не плохо , чтобы использовать джокер с оператором импорта Java.
В чистом коде Роберт С. Мартин фактически рекомендует использовать их, чтобы избежать длинных списков импорта.
Вот рекомендация:
J1: избегайте длинных списков импорта, используя подстановочные знаки
Если вы используете два или более классов из пакета, импортируйте весь пакет с
импортная упаковка. *;
Длинные списки импорта пугают читателя. Мы не хотим загромождать вершины наших модулей с 80 линиями импорта. Скорее мы хотим, чтобы импорт был кратким заявлением о том, с какими пакетами мы сотрудничаем.
Конкретный импорт - это жесткие зависимости, тогда как импорт с подстановочными знаками - нет. Если вы специально импортируете класс, то этот класс должен существовать. Но если вы импортируете пакет с подстановочным знаком, никаких особых классов не должно быть. Оператор импорта просто добавляет пакет в путь поиска при поиске имен. Таким образом, при импорте не создается никакой реальной зависимости, и поэтому они служат для того, чтобы наши модули были менее связанными.
Есть моменты, когда длинный список конкретных импортов может быть полезен. Например, если вы имеете дело с унаследованным кодом и хотите выяснить, для каких классов вам нужно создавать макеты и заглушки, вы можете пройти по списку определенных импортов, чтобы найти истинные квалифицированные имена всех этих классов, а затем поставить соответствующие заглушки на месте. Тем не менее, это использование для конкретного импорта очень редко. Кроме того, большинство современных IDE позволяют вам конвертировать импортируемые символы в список определенных импортов с помощью одной команды. Так что даже в устаревшем случае лучше импортировать подстановочные знаки.
Импорт подстановочных знаков может иногда вызывать конфликты имен и неоднозначности. Два класса с одинаковыми именами, но в разных пакетах, должны быть специально импортированы или, по крайней мере, специально квалифицированы при использовании. Это может быть неприятно, но достаточно редко, когда использование подстановочного импорта все же обычно лучше, чем определенный импорт.
Производительность : не влияет на производительность, так как байт-код одинаков. хотя это приведет к некоторым издержкам компиляции.
Компиляция : на моем персональном компьютере компиляция пустого класса без импорта чего-либо занимает 100 мс, но тот же класс при импорте java. * Занимает 170 мс.
import java.*
ничего не импортирует. Почему это имеет значение?
Это загромождает ваше пространство имен, требуя от вас полного указания любых двусмысленных имен классов. Наиболее распространенным случаем этого является:
import java.util.*;
import java.awt.*;
...
List blah; // Ambiguous, needs to be qualified.
Это также помогает конкретизировать ваши зависимости, так как все ваши зависимости перечислены вверху файла.
В большинстве мест, где я работал, где используется сколько-нибудь значительное количество Java, явный импорт является частью стандарта кодирования. Иногда я все еще использую * для быстрого создания прототипов, а затем расширяю списки импорта (некоторые IDE будут делать это и для вас) при создании кода.
В предыдущем проекте я обнаружил, что переход от * -импортов к конкретным импортам сокращает время компиляции вдвое (с примерно 10 минут до примерно 5 минут). * -Import заставляет компилятор искать в каждом из перечисленных пакетов класс, соответствующий тому, который вы использовали. Хотя это время может быть небольшим, оно складывается для больших проектов.
Побочным эффектом * -import было то, что разработчики будут копировать и вставлять общие строки импорта, а не думать о том, что им нужно.
В какой бы технологии разработки не была основана реализация, ищите способы минимизировать работу по рефакторингу МОДУЛЕЙ. В Java нет возможности избежать импорта в отдельные классы, но вы можете по крайней мере импортировать целые пакеты за раз, отражая намерение, что пакеты являются очень связными единицами, одновременно уменьшая усилия по изменению имен пакетов.
И если он загромождает локальное пространство имен, это не ваша вина - виноват размер пакета.
Влияния во время выполнения не происходит, так как компилятор автоматически заменяет * конкретными именами классов. Если вы декомпилируете файл .class, вы никогда не увидите import ...*
.
C # всегда использует * (неявно), так как вы можете только using
имя пакета. Вы никогда не можете указать имя класса вообще. Java вводит эту функцию после c #. (Java очень сложен во многих аспектах, но это выходит за рамки этой темы).
В Intellij Idea, когда вы «организуете импорт», он автоматически заменяет несколько импортов одного пакета на *. Это обязательная функция, так как вы не можете отключить ее (хотя вы можете увеличить порог).
Случай, указанный в принятом ответе, недействителен. Без * у вас все еще та же проблема. Вам необходимо указать имя pakcage в вашем коде независимо от того, используете вы * или нет.
Для записи: когда вы добавляете импорт, вы также указываете свои зависимости.
Вы могли быстро увидеть, каковы зависимости файлов (исключая классы одного и того же пространства имен).
Наиболее важным является то, что импорт java.awt.*
может сделать вашу программу несовместимой с будущей версией Java:
Предположим, что у вас есть класс с именем «ABC», вы используете JDK 8 и импортируете java.util.*
. Теперь предположим, что выходит Java 9, и у нее есть новый класс в пакете, java.util
который по совпадению также называется «ABC». Ваша программа теперь не будет компилироваться на Java 9, потому что компилятор не знает, подразумеваете ли вы с именем «ABC» свой собственный класс или новый класс вjava.awt
.
У вас не будет этой проблемы, если вы импортируете только те классы, которые явно java.awt
используются.
Ресурсы:
Stream
в качестве примера новый класс, добавленный в Java в java.util в Java 8 ...
Среди всех правильных замечаний, высказанных с обеих сторон, я не нашел своей основной причины избегать подстановочного знака: мне нравится иметь возможность читать код и непосредственно знать, что представляет собой каждый класс, или его определение не на языке или файл, где его найти. Если импортировано более одного пакета с *, мне нужно поискать каждый из них, чтобы найти класс, который я не узнаю. Читаемость является высшей, и я согласен, что код не должен требовать IDE для его чтения.