Почему использование подстановочного знака с оператором импорта Java - это плохо?

Гораздо удобнее и чище использовать один оператор, например

import java.awt.*;

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

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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
461
0
165 624
17
Перейти к ответу Данный вопрос помечен как решенный

Ответы 17

Ответ принят как подходящий

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

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

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

Это первый сценарий, который случится. Компилятор замечает наличие двух классов событий и выдает ошибку.

jan.vdbergh 29.09.2008 09:52

Обязательно ознакомьтесь с моим комментарием ниже - есть большая проблема с типами, которые со временем добавляются в сторонние библиотеки. У вас может быть компилируемый код, который перестает компилироваться после того, как кто-то добавит тип в jar, от которого вы зависите.

Scott Stanchfield 29.09.2008 23:42

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

Kip 11.06.2009 06:34

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

rpjohnst 29.09.2011 19:47

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

mobiusinversion 18.10.2020 18:04

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

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

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

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

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

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

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

Мне нравится большинство ваших пунктов, но именно №4 заставило меня проголосовать за ваш ответ. Современные IDE удаляют большинство аргументов против использования явного импорта ...

Sheldon R. 21.01.2014 20:04

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

LegendLength 07.01.2016 06:33

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

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

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

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

import java.sql.*;
import java.util.*;
import java.sql.Date;

Я согласен. Хотя я не возражаю против использования явного импорта, я все же предпочитаю использовать импорт звездочки. Они подчеркивают, что «единица повторного использования» - это весь пакет, а не его отдельные типы. Другие причины, перечисленные против импорта звезд, являются слабыми, и, по моему опыту, использование импорта звезд никогда не вызывало реальных трудностей.

Rogério 19.07.2009 02:24

См. javadude.com/articles/importondemandisevil.html, чтобы узнать, почему это зло. Основная идея: это может привести к прекращению компиляции кода, когда классы являются добавлен для пакетов, которые вы импортируете (например, когда List был добавлен в java.util ...)

Scott Stanchfield 01.05.2012 20:21

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

davetron5000 02.05.2012 00:21

Все упомянутые вами проблемы могут быть решены с помощью современных IDE (сокрытие импорта, рефакторинг имени класса и т. д.).

assylias 05.02.2013 12:10

Мне не нужно использовать IDE для чтения или записи исходного кода - код должен быть читаемым сам по себе без специальных инструментов, если только язык не является невероятно тупым. В этом случае Java отлично работает - просто используйте импорт звездочки. Нет причин не делать этого.

davetron5000 09.02.2013 00:14

Импорт статических звезд дает прирост производительности. Удобно просто набрать assertTrue и т. д. Моя среда IDE настроена с использованием правил стиля проверки для моей работы, которые их запрещают. Затем для добавления статического импорта требуется преобразование существующего импорта (вручную или с помощью ярлыка). В этот момент я могу либо вручную изменить импорт на звезду (необходимо изменить позже), либо повторить описанный выше процесс для всех других методов / констант / перечислений, которые я использую. Это незначительное, но реальное нарушение. Список был неудачным; Я никогда не сталкивался с этой или подобной проблемой. Спасибо за внимание.

Donal 23.01.2014 01:41

@ davetron5000 Вам не нужно использовать IDE для чтения или записи исходного кода. Все приличные текстовые редакторы также поддерживают сворачивание.

David Conrad 25.07.2014 19:44

Даже дядя Боб рекомендует выполнять импорт пакетов в своей книге «Чистый код». Для меня это достаточно веская причина использовать их.

Sergei Tachenov 24.06.2016 09:02

@ davetron5000 Если ваш код содержит 10+ импортированных подстановочных знаков, и вы используете класс Foo, и если я прочитал ваш код без использования IDE (поскольку ваш аргумент состоит в том, что мне не нужно его использовать), как я узнаю, какой пакет Foo пришли из? Конечно, при использовании IDE среда IDE сообщит мне об этом, но весь ваш аргумент состоит в том, что я должен иметь возможность читать кода без него. Выполнение явного импорта помогает задокументируйте код(отличная причина избегать использования подстановочных знаков), и гораздо более вероятно, что я буду кодом чтение без использования IDE, чем пишу кодом без использования IDE.

Andreas 12.01.2017 21:01

Ответ: «Оператор импорта предназначен для импорта пакета, а не класса». Моя IDE: [Java] Only a type can be imported. org.springframework.stereotype resolves to a package

Brent Bradburn 21.03.2018 22:36

Если у вас есть сотня импортов, скорее всего, ваш класс слишком велик и, вероятно, отвечает более чем за одну вещь. Проблема здесь не в импорте, а в написанном коде. Вы должны избавиться от испорченного материала, вместо того, чтобы делать его красивым, придавая ему форму цветка. ;)

Amadán 05.09.2018 14:23

@ davetron5000 Вы опровергли свой аргумент. Чтобы код «читался сам по себе без специальных инструментов», у вас должен быть полностью квалифицированный импорт. Используя импорт с подстановочными знаками, вы не знаете, откуда берется класс, без поиска по пакетам или использования справки при наведении курсора IDE.

Nathan Niesen 26.07.2019 21:08

Некоторое время назад я был программистом по обслуживанию. У меня часто был код читать на Github или vi. Проблема с начальным импортом в том, что очень сложно найти, откуда берется этот определенный класс. Худшим способом было выполнить поиск по всему репозиторию или выполнить команду grep, оба варианта кажутся излишними. Я хотел, чтобы люди не использовали * импорт. И теперь я не знаю, сказано ли об этом в «Чистом коде».

Ganesh Satpute 21.12.2019 21:14

@GaneshSatpute Итак, вы только что доказали, что вам не следует использовать GitHub или vi для просмотра репозиториев. Я считаю, что правило «не следует использовать специальные инструменты для чтения кода» не годится. Мы профессионалы, мы должны использовать оптимальные (если не самые лучшие) инструменты, а не наоборот.

user3157855 20.08.2020 17:18

@ user3157855 Я точно ничего не доказал. Я до сих пор использую vi, Github, а также современные IDE. Я стараюсь быть непредубежденным, я не буду считать кого-то «непрофессиональным», потому что он использует vi или Github, чтобы показать кому-то код, или быстро посмотреть на реализацию, а не клонировать репозиторий и настраивать его локально.

Ganesh Satpute 20.08.2020 18:01

пожалуйста, смотрите мою статью Импорт по требованию - это зло

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

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

// ...

List list;

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

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

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

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

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

Это не оправдание. Если вы меняете версию java, вы каким-то образом ожидаете, что что-то не удастся, то же самое, если вы измените версию двоичного файла, который использует ваш код. В этих случаях код выдает ошибку компиляции, и ее легко исправить (см. Предыдущий ответ: stackoverflow.com/a/149282/7595)

Pablo Fernandez 06.04.2012 04:44

@PabloFernandez - Нет - если я проверю код, который хранился в репозитории в течение года, он все равно должен компилироваться. Импорт по требованию может легко завершиться ошибкой, если новые классы имеют значение добавлен для существующих пакетов, которые я импортировал. Это проблема не только при обновлении версий Java. Также - если API спроектирован хорошо, никогда должен нарушить существующий код при обновлении. Единственный раз, когда мне потребовалось изменить код при обновлении версий java, было из-за импорта по запросу и когда Sun втянула XML API в среду выполнения java.

Scott Stanchfield 01.05.2012 20:24

Я придаю большое значение языковой функции, которая заставляет некогда компилируемый код прекращать компиляцию, когда вы добавляете что-то в путь к классу. Очень большая проблема, особенно когда сопровождающий берет код, который они не писали - как они узнают намерение, не изучая код какое-то время - код, который раньше компилировался и отлично работал ... Почему они должны его менять только потому, что к пути компиляции был добавлен новый jar или обновлен JDK?

Scott Stanchfield 24.12.2012 09:57

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

Pablo Fernandez 24.12.2012 18:29

ДОБАВЛЕНИЕ класса (с уникальным, полностью определенным именем!) В путь к классам не должно ни на что влиять. Дело в том, что если вы не используете синтаксис импорта по запросу, этого не произойдет. Так что не используйте плохой синтаксис, который, к сожалению, допускает язык, и это еще одна реальная проблема, с которой вы можете столкнуться.

Scott Stanchfield 25.12.2012 00:43

Суть моего ответа в том, что это ненужная языковая функция, которая вызывает проблемы. Многие IDE / редакторы автоматически обрабатывают расширение импорта. Используйте полностью квалифицированный импорт, и вероятность возникновения этой конкретной ошибки отсутствует. Меня поразило это, когда я был вынужден исправить ошибку в существующем коде, и вам действительно не нужно что-то подобное, чтобы отвлечься от реальной задачи. java.util.List против java.awt.List не так уж и плохо, чтобы понять, но попробуйте, когда имя класса - Configuration, и несколько библиотек зависимостей добавили его в свою последнюю версию репозитория maven.

Scott Stanchfield 25.12.2012 00:53

Если я обновлю jar-файл, в котором классы, которые я использую, совместимы с API-forward, И я не использую синтаксис импорта по запросу, это никак не повлияет на меня. Это имеет для вас смысл? Не поленитесь определить импорт, и это не проблема. Синтаксис импорта по запросу был ошибкой в ​​определении языка Java; разумный язык не должен допускать подобных ошибок.

Scott Stanchfield 28.12.2012 04:04

В статье Скотта он утверждает, что если бы Sun создала java.util.collections.List вместо java.util.List, не было бы конфликта с java.awt.List. Это почему?

Sheldon R. 21.01.2014 20:15

@SheldonR., Потому что, если бы они изобрели новый пакет (java.util.collections) для List, у устаревшего кода не было бы риска импортировать его по ошибке.

aioobe 03.06.2015 23:34

@aioobe Разве java.util.collections не будет подхвачен java.util. *?

Sheldon R. 05.06.2015 23:03

@aioobe Пакеты в Java - это просто уникальные имена. Они могут выглядеть как вложенные имена из-за общих префиксов, но они никогда не имеют отношения к другим пакетам. (Обратите внимание, что они имеют общие структуры родительских каталогов, но это просто удобство среды, а не определение языка ...)

Scott Stanchfield 05.06.2015 23:26

Думаю, ваш комментарий должен был быть адресован SheldonR.

aioobe 05.06.2015 23:28

@aioobe (я хотел, чтобы он перешел к вам, чтобы добавить пояснение, почему java.util.collections не будет получен при импорте java.util. *)

Scott Stanchfield 09.06.2015 17:45

Хорошо, спасибо за ваш комментарий, но вам не нужно учить меня, как работают пакеты Java. :-D (Я зарабатываю на жизнь компилятором OpenJDK Java ;-)

aioobe 09.06.2015 17:53

Обратите внимание, что конкретный импорт имеет приоритет над импортом с подстановочными знаками. import java.awt.*; import java.util.*; import java.util.List; достаточно, чтобы устранить неквалифицированный List. Это намного чище, чем называть каждый класс.

Kevin 06.02.2016 07:10

@Kevin Импорт подстановочных знаков Любые подвергает вас риску того, что код не компилируется при добавлении новой сторонней зависимости или обновлении до более поздней версии Java. Имея доступные IDE, вы всегда можете свернуть список импорта, чтобы не смотреть на него

Scott Stanchfield 10.02.2016 16:02

@ScottStanchfield Обновление часто вызывает незначительные головные боли, но вероятность того, что обновление приведет к тому, что ранее однозначное имя станет неоднозначным, довольно редка, так что не стоит беспокоиться.

Kevin 15.02.2016 00:56

И, на мой взгляд, «читабельность в среде IDE» недостаточно. Код должен быть легко читаемым в любом текстовом редакторе, даже в тех, которые не выполняют сворачивание импорта или кода.

Kevin 15.02.2016 00:56

@Kevin - проблема заключается между удобочитаемостью в редакторах, которые не поддерживают сворачивание (я бы сказал, что не большинство из используемых), и огромным потенциалом ошибок компилятора, вносимых изменениями библиотеки. Я видел, как этот потенциал реализовывался много раз (самый ранний и самый отвратительный - List в java.util. * И java.awt. *), Потому что разработчики используют импорт по запросу, и это чаще всего влияет на человека, поддерживающего код. год или более спустя, что обременяет их за счет читабельности вашего слабого редактора. Не обременяйте своих сопровождающих. И получите лучший редактор.

Scott Stanchfield 17.02.2016 02:34
«Нет НИКАКОЙ причины, по которой код должен прекращать компиляцию только потому, что в пакет добавлен тип» - this can also be a problem, when an enum was extended with a new type.
Dávid Horváth 23.08.2016 17:51

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

Paul Cunningham 24.07.2020 18:36

Также возвращение к Java 1.1 -> Java 1.2 в качестве примера недопустимо. Это было ГЛАВНОЕ изменение парадигмы, и тонна существующего кода Java сломалась во время этого перехода.

Paul Cunningham 24.07.2020 18:41

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

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

Для этого должно быть много строк импорта или система разработки действительно жалкий. Я использую import- * и могу скомпилировать свой вся кодовая база из 2107 классов менее чем за 2 минуты.

Lawrence Dol 06.03.2010 01:37

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

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

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

J1: Avoid Long Import Lists by Using Wildcards

If you use two or more classes from a package, then import the whole package with

import package.*;

Long lists of imports are daunting to the reader. We don’t want to clutter up the tops of our modules with 80 lines of imports. Rather we want the imports to be a concise statement about which packages we collaborate with.

Specific imports are hard dependencies, whereas wildcard imports are not. If you specifically import a class, then that class must exist. But if you import a package with a wildcard, no particular classes need to exist. The import statement simply adds the package to the search path when hunting for names. So no true dependency is created by such imports, and they therefore serve to keep our modules less coupled.

There are times when the long list of specific imports can be useful. For example, if you are dealing with legacy code and you want to find out what classes you need to build mocks and stubs for, you can walk down the list of specific imports to find out the true qualified names of all those classes and then put the appropriate stubs in place. However, this use for specific imports is very rare. Furthermore, most modern IDEs will allow you to convert the wildcarded imports to a list of specific imports with a single command. So even in the legacy case it’s better to import wildcards.

Wildcard imports can sometimes cause name conflicts and ambiguities. Two classes with the same name, but in different packages, will need to be specifically imported, or at least specifically qualified when used. This can be a nuisance but is rare enough that using wildcard imports is still generally better than specific imports.

Я бы посоветовал Роберту К. Мартину использовать лучшие шаблоны для создания более сжатых пакетов и собственных классов, не требующих 80 строк импорта. То, что множество классов, необходимых для импорта внутри одного класса, просто умоляет: «Энтропия, энтропия, сломай меня, пожалуйста ...» и указывает причину, по которой следует избегать импорта *, изложенную в ответах Скотта Стэнчфилдса.

Ray 24.11.2014 01:04

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

user4229245 31.07.2015 04:07
Длинные списки импорта устрашают читателя. -- This assertion has an invalid presumption. Programmers are not required to read source code from top to bottom. We may not read import lists at all. When we do, we might read only one of the imports, for clarification. At other times, the imports may be collapsed entirely, if we're working in an IDE. Regardless of the source, today this is now bad advice.
Andy Thomas 28.04.2016 20:39

Просто чтобы обеспечить некоторый противовес, когда дело доходит до цитирования авторитетов по этой проблеме: Руководство по стилю Google Java, а также Руководство по стилю Java в Twitter (который в значительной степени основан на Google, чтобы быть справедливым) специально запрещают импорт подстановочных знаков. Но они не дают никакого обоснования этому решению.

anothernode 06.09.2017 14:53

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

Ganesh Satpute 21.12.2019 21:16

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

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

import java.* ничего не импортирует. Какая разница?

user207421 09.11.2015 22:34

Это имеет значение, потому что он ищется во время компиляции.

LegendLength 07.01.2016 06:34

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

kugo2006 29.07.2020 17:12

В Книга DDD

In whatever development technology the implementation will be based on, look for ways of minimizing the work of refactoring MODULES . In Java, there is no escape from importing into individual classes, but you can at least import entire packages at a time, reflecting the intention that packages are highly cohesive units while simultaneously reducing the effort of changing package names.

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

Наиболее важным из них является то, что импорт java.awt.* может сделать вашу программу несовместимой с будущей версией Java:

Предположим, у вас есть класс с именем «ABC», вы используете JDK 8 и импортируете java.util.*. Теперь предположим, что выходит Java 9, и у нее есть новый класс в пакете java.util, который по совпадению также называется «ABC». Теперь ваша программа не будет компилироваться на Java 9, потому что компилятор не знает, имеете ли вы под именем «ABC» свой собственный класс или новый класс в java.awt.

У вас не возникнет этой проблемы, если вы явно импортируете из java.awt только те классы, которые вы действительно используете.

Ресурсы:

Импорт Java

совет: вы могли бы использовать Stream в качестве примера нового класса, добавленного в Java в java.util в Java 8 ...

Clint Eastwood 24.07.2017 17:08

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

Если вы доведете это до полного логического завершения, тогда ваш стиль должен заключаться в том, чтобы вообще не использовать импорт, а вместо «нового LinkedList» всегда использовать «new java.util.LinkedList» и делать это последовательно везде.

Erwin Smout 28.09.2018 11:33
  • Это не влияет на время выполнения, поскольку компилятор автоматически заменяет * конкретными именами классов. Если вы декомпилируете файл .class, вы никогда не увидите import ...*.

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

  • В Intellij Idea, когда вы "организуете импорт", он автоматически заменяет несколько импортированных одного и того же пакета на *. Это обязательная функция, так как вы не можете отключить ее (хотя вы можете увеличить порог).

  • Случай, указанный в принятом ответе, недействителен. Без * у вас все еще та же проблема. Вы должны указать имя pakcage в своем коде, независимо от того, используете вы * или нет.

В IntelliJ это не обязательная функция, и ее можно отключить.

Bastien7 18.10.2019 12:12

Для записи: Когда вы добавляете импорт, вы также указываете свои зависимости.

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

Соглашаться. Мотиватор не столько в производительности или компиляции, сколько в удобочитаемости вашего кода. Представьте, что вы читаете код без IDE - например, на GitHub. Внезапно поиск каждой ссылки, не определенной в файле, который вы читаете, становится утомительно утомительно.

Leo Orientis 27.10.2019 14:52

Импорт всех классов в пакете считается слепым подходом. Основная причина этого в том, что это загромождает пространство имен классов и может привести к конфликтам между классами в разных пакетах с одинаковыми именами.

Специальное заполнение необходимых классов позволяет избежать этой проблемы и ясно показывает, какие версии нужны. Это хорошо для удобства сопровождения кода.

Забудьте о загроможденных пространствах имен ... И подумайте о бедняге, который должен читать и понимать ваш код на GitHub, в vi, Notepad ++ или в каком-либо другом текстовом редакторе, отличном от IDE.

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

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

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

Вот несколько вещей, которые я нашел по этой теме.

  • Во время компиляции компилятор пытается найти классы, которые используются в коде из. * Import, и соответствующий байт-код будет сгенерирован путем выбора используемых классов из. * Import. Таким образом, байтовый код использования. * Import или .class names import будет таким же, и производительность во время выполнения также будет такой же из-за того же байтового кода.

  • В каждой компиляции компилятор должен сканировать все классы пакета. * На соответствие классам, которые фактически используются в коде. Таким образом, код с. * Import занимает больше времени в процессе компиляции по сравнению с использованием импорта имени .class.

  • Использование. * Import помогает сделать код более чистым

  • Использование. * Import может создать двусмысленность, когда мы используем два класса с одинаковым именем из двух разных пакетов. Например, Дата доступна в обоих пакетах.

      import java.util.*;
      import java.sql.*;
    
      public class DateDemo {
          private Date utilDate;
          private Date sqlDate;
      }
    

Другие вопросы по теме