Есть ли причина для очистки неиспользуемого импорта в Java, кроме уменьшения беспорядка?

99

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

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

Кип
источник

Ответы:

86

Я не думаю, что проблемы с производительностью или что-то в этом роде вероятны, если вы не удаляете импорт.

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

В Eclipse вы всегда можете использовать ярлык (в зависимости от ОС - Win: Ctrl + SHIFT + Oи Mac :) COMMAND + SHIFT + Oдля организации импорта. Затем Eclipse очищает раздел импорта, удаляет весь устаревший импорт и т. Д. Если вам снова понадобится импортированная вещь, eclipse добавит их автоматически, пока вы завершаете оператор с помощьюCtrl + SPACE . Таким образом, нет необходимости хранить неиспользуемый код в вашем классе.

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

Януш
источник
22
На самом деле это Ctrl + Shift + O в окнах.
Мэтт Болл,
1
Ctrl + Shift + O на Linux хорошо. Наверное, то же самое и на BSD.
WhyNotHugo
2
Другой способ получить к нему действие организовать импорт - щелкнуть ctrl+3(по крайней мере, на windwos), а затем ввести импорт. Он явно медленнее, чем ctrl + shift + O, но это способ быстро найти его (и многие другие действия, которые вы либо помните, либо просто пытаетесь найти), даже если вы не помните конкретный ярлык для этого.
epeleg
53

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

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

Приложение: сегодня на сервере сборки начались сбои компиляции (даже не запуск теста) с ошибкой нехватки памяти. Он всегда работал нормально, и при проверке не было никаких изменений в процессе сборки или существенных дополнений, которые могли бы это объяснить. После попытки увеличить настройки памяти (это работает с 64-битной JVM на 64-битной CentOS!) До чего-то, что выходит далеко за рамки того, где клиенты могут компилировать, я исследовал проверки одну за другой.

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

Ишай
источник
4
@Yishai, если вы используете Eclipse, просмотрите действия по сохранению, которые могут нормализовать исходный код при каждом сохранении.
Торбьёрн Равн Андерсен
2
@EJP, хотя они не влияют на результирующий байт-код, компилятору необходимо разрешить их, чтобы понять байт-код, который ему нужно создать.
Ишай
3
@EJP, все приложение говорит о времени компиляции («сервер сборки начал сбой компиляции»).
Ишай
1
Я до сих пор не понимаю, как один только импорт мог все это вызвать?
Thorbjørn Ravn Andersen
1
@Yishai Извините, но я не верю. Вы поставили неверный диагноз. Импорт не должен иметь такого эффекта, если класс действительно не использовался. Все, что делает оператор импорта, - это сообщает компилятору, в каком пакете находится этот класс. Компилятор пытается неявно скомпилировать только тогда, когда ему нужна информация о типе этого класса.
Маркиз Лорн,
9

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

Например, предположим, что ваша программа использует класс com.XYZObjectPool, и что позже вы решите не использовать его, но никогда не удаляете импорт. Если кто-то еще хочет создать экземпляр org.WVYObjectPool и просто сослаться на ObjectPool, он не получит никаких предупреждений об этом до тех пор, пока где-то внизу не возникнет проблема с преобразованием или вызовом.

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

В любом случае вы можете попросить Eclipse очистить их за вас.

Ури
источник
3

Предупреждение? Попросите Eclipse автоматически очистить их для вас. Это то, что делает IntelliJ. Если он достаточно умен, чтобы предупредить вас, он должен быть достаточно умен, чтобы убрать их. Я бы порекомендовал поискать настройку Eclipse, чтобы она перестала быть такой придиркой и сделала что-нибудь.

Duffymo
источник
4
Это Сохранение Действия. Лично мне нравится, что Eclipse изменяет ваш код только тогда, когда вы явно об этом просили.
Торбьорн Равн Андерсен
1
@ Thorbjørn: Согласен, особенно если это класс, который я немного перестал использовать, но который, как я ожидаю, скоро снова добавят.
Donal Fellows
2
@Donal, ну, для этого и нужен Ctrl-Space.
Торбьорн Равн Андерсен
3

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

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

Подумайте о следующем сценарии:

import company.billing.*;
import company.humanrerources.*;

// other imports 


class SomeClass {
      // hundreds or thousands of lines here... 
    public void veryImportantMethod() {
      Customer customer;
      Employee comployee;
      Department dept. 
      // do something with them
     }
 }

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

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

Если это для личного проекта или чего-то небольшого, это действительно не имеет значения, но для чего-то большего, что должно использоваться другими разработчиками (и поддерживаться на протяжении многих лет), это ДОЛЖНО БЫТЬ.

Нет абсолютно никакой разницы в производительности ни с одним.

OscarRyz
источник
3

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

Автоматическое удаление импорта во время операции сохранения вызвало у меня некоторое горе, когда, например, во время разработки или тестирования у вас возникла проблема и вы закомментировали некоторый код, когда вы его сохраняете, импорт, используемый закомментированным разделом кода, удаляется. Иногда это не проблема, поскольку вы можете отменить ( Ctrl+ Z) изменения, но в других случаях это не так просто, как вы, возможно, внесли другие изменения. У меня также была проблема, когда, когда я раскомментировал код (я ранее закомментировал, а затем сохранил, таким образом удалив импорт для этого кода), он автоматически пытался угадать, какие импорта были необходимы, и выбрал неправильные (например, я думаю, что я был использован StringUtilsкласс, и он выбрал другой с тем же именем из неправильной библиотеки).

Я предпочитаю упорядочивать импорт вручную, а не сохранять его.

Джон
источник
2

Для eclipse я использую это: окно -> настройки -> java -> редактор -> сохранить действие -> установите флажок для организации импорта (там также есть много других полезных вещей, таких как форматирование, создание окончательных полей и так далее. .). Поэтому, когда я сохраняю свой файл, eclipse удаляет для меня импорт unessacry. На мой взгляд, если вам что-то не нужно, удалите это (или позвольте удалить затмением).

кукудас
источник
2

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

Шарон
источник
2
@DimaSan На самом деле это так: вопрос говорит, что я не хочу удалять импорт, пока я не уверен, что закончил проектирование класса.
The Vee
1

Никакого влияния на производительность нет, хотя для удобочитаемости можно очистить. Удалить неиспользуемый импорт довольно просто как в Eclipse, так и в IntelliJ IDEA.

Затмение

Windows / Linux -    Ctrl+Shift +O

Mac -                        Cmd+ Shift+O

IntelliJ IDEA или Android Studio

Windows / Linux -    Ctrl+Alt +O

Mac -                        Cmd+ Alt+O

Мадан Сапкота
источник
0

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

И, кстати, с eclipse вы можете использовать Ctrl+ Shift+ Oдля организации импорта, но вы также можете настроить «очиститель», который имеет дело с такими вещами (и многими другими) каждый раз, когда вы сохраняете файл java.

Майкл Зильберманн
источник
хмм .. я был бы удивлен, если бы это было такое поведение .. я знаю, что классы не инициализируются (т.е. вызывают статические инициализаторы) до первого использования или до тех пор, пока они не будут специально запрошены пользовательским загрузчиком. но если под «загруженным» вы имеете в виду просто «прочитано в память, но не обработано», это возможно, хотя я в этом сомневаюсь.
Кип,
на самом деле, если подумать, это должно быть довольно легко проверить. скомпилируйте код с неиспользуемым импортом, затем воспользуйтесь инструментом «декомпиляции» и посмотрите, остались ли неиспользуемые импорты или нет. если нет, то либо они удаляются компилятором, либо просто для удобства программиста.
Кип,
4
Где ты это читал? Это полностью и совершенно неверно, и всегда было так. Каждый класс , на который ссылается код будет загружен, не включая импорт.
Маркиз Лорн,
0

Для меня один неиспользованный импорт класса в классе контроллера создал проблему компиляции в сборке Jenkins после того, как я удалил импортированный класс во время очистки кода и зафиксировал удаление в git без тестирования сборки на локальном уровне.

Аакаш Кедиа
источник