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


99

Чи є якісь вагомі причини уникати невикористаних заяв про імпорт на Java? Як я розумію, вони є для компілятора, тому багато невикористаного імпорту не матимуть ніякого впливу на компільований код. Це просто для зменшення безладу та уникнення називання конфліктів вниз?

(Я запитую, тому що Eclipse попереджає про невикористаний імпорт, що дратує, коли я розробляю код, тому що я не хочу видаляти імпорт, поки я не впевнений, що закінчую розробку класу.)

Відповіді:


86

Я не думаю, що проблеми з роботою або щось подібне, ймовірно, якщо ви не знімаєте імпорт.

Але можуть бути іменні конфлікти, в рідкісних випадках, наприклад, імпорт списку інтерфейсів.

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

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


22
Це насправді Ctrl + Shift + O на windows.
Метт Бал

1
Ctrl + Shift + O на Linux добре. Напевно, те саме на BSD.
WhyNotHugo

2
Інший спосіб дістатись до акції організованого імпорту - натисканням ctrl+3(принаймні на windwos) та введенням імпорту. Це, очевидно, повільніше, ніж тоді ctrl + shift + O, але це спосіб швидко знайти його (та багато інших дій, які ви або пам’ятаєте, або просто намагаєтесь знайти), навіть якщо ви не пам'ятаєте конкретний ярлик для цього.
epeleg

53

Одне було б те, що якщо ви видалите клас, на який посилається імпорт, з classpath, ви не отримаєте дурної помилки компілятора, яка не слугувала ніякій меті. І ви не отримаєте помилкових позитивних результатів, коли будете виконувати пошук "там, де використовується".

Іншим (але це було б дуже специфічним за своєю суттю) було б, якби невикористаний імпорт мав назвати конфлікт з іншим імпортом, через що ви без потреби користуєтесь повністю кваліфікованими іменами.

Додаток: Сьогодні сервер збірки почав збій компіляції (навіть не тестовий запуск) із помилкою пам'яті. Він пройшов нормально назавжди, і при реєстрації не було змін у процесі збирання чи істотних доповнень, які могли б пояснити це. Після спроби збільшити налаштування пам’яті (це працює 64-бітний JVM на 64-бітному CentOS!) На щось набагато більше, ніж клієнти могли складати, я перевіряв контрольно-розбіркові документи одна за одною.

Розробник використав і відмовився від неправильного імпорту (вони використовували клас, автоматично імпортували його, а потім зрозуміли, що це помилка). Цей невикористаний імпорт потягнув на цілий окремий рівень програми, яка, хоча IDE не налаштована розділяти їх, процес збирання є. Цей єдиний імпорт затягнувся у стільки класів, що компілятор намагався компілювати, не маючи відповідних залежних бібліотек на classpath, що це викликало стільки проблем, що викликало помилку в пам'яті. Щоб вирішити цю проблему, викликану невикористаним імпортом, знадобилася година.


4
@Yishai, якщо ви використовуєте Eclipse, перегляньте Збереження дій, яке може нормалізувати вихідний код кожного разу, коли ви зберігаєте.
Thorbjørn Ravn Andersen

2
@EJP, хоча вони не впливають на отриманий байт-код, компілятору необхідно вирішити їх, щоб зрозуміти байт-код, який він повинен створити.
Ісіхай

3
@EJP, весь додаток говорить про час компіляції ("сервер побудови почав збій компіляції").
Yishai

1
Я досі не розумію, як саме імпорт міг спричинити все це?
Торбьорн Равн Андерсен

1
@Yishai Вибачте, але я не вірю. Ви неправильно діагностували це. Імпорт не повинен мати такого ефекту, якщо клас не був фактично використаний. Усі операції імпорту - це сказати компілятору, в якому пакеті знаходиться цей клас. Компілятор намагається компілювати лише неявно, коли йому потрібна інформація про тип цього класу.
Маркіз Лорн

9

З точки зору пуристу, будь-яка залежність є "обмеженням" для продукту і, таким чином, може пізніше викликати проблеми з технічним обслуговуванням.

Наприклад, припустимо, що ваша програма використовує клас com.XYZObjectPool, і ви згодом вирішите не використовувати її, але ніколи не видаляйте імпорт. Якщо хтось зараз хоче створити org.WVYObjectPool і просто звернутися до ObjectPool, вони не отримують жодного попередження про це, поки десь внизу лінії не з’явиться проблема кастингу або виклик.

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

У будь-якому випадку ви можете попросити Eclipse очистити їх для себе


3

Увага? Попросіть Eclipse автоматично очистити їх для вас. Саме цим займається IntelliJ. Якщо це досить розумно, щоб попередити вас, воно повинно бути досить розумним, щоб їх почистити. Я рекомендую шукати налаштування Eclipse, щоб сказати, щоб він перестав бути таким гнотом і щось робити.


4
Це збереження дій. Особисто мені подобається, що Eclipse змінює ваш код лише тоді, коли ви прямо попросили його.
Thorbjørn Ravn Andersen

1
@ Thorbjørn: Погодився, особливо якщо це клас, який я трохи перестала використовувати, але якого, як я очікую, незабаром знову додаду.
Стипендіати доналу

2
@Donal, ну, саме для цього Ctrl-Space.
Thorbjørn Ravn Andersen

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 ви не хочете, щоб навести курсор чи перейти до декларації та повернення, простіше, якщо ви розумієте з точки зору функціональності, від чого залежать інші пакети та класи, від яких залежить поточний код.

Якщо це для особистого проекту чи чогось невеликого, це насправді не має значення, але для чогось більшого, що повинні бути використані іншими розробниками (і підтримуватися протягом років), це ОБОВ'ЯЗКОВО БУДЕ.

Існує абсолютно немає різниці в продуктивності ні з одним.


3

FYI, Це мене зловило, оскільки я не думав, що організація імпорту фактично видалила невикористаний імпорт, я подумав, що це просто сортувало їх.

Автоматичне видалення імпорту під час операції збереження викликало у мене певне горе, коли, наприклад, під час розробки або тестування виникли проблеми і прокоментували якийсь код, коли ви зберігаєте його, імпорт, який використовується коментованим розділом коду, видаляється. Іноді це не проблема, оскільки ви можете скасувати ( Ctrl+ Z) зміни, але в інших випадках це не так просто, як, можливо, ви внесли інші зміни. Також у мене виникла проблема, коли коли я коментував код (я раніше коментував, а потім зберігав, видаляючи імпорт цього коду), він автоматично намагався відгадати необхідний імпорт і виявив неправильні (наприклад, я думаю, що я мавStringUtils клас, і він вибрав ще один із такою ж назвою з неправильної бібліотеки).

Я вважаю за краще вручну організовувати імпорт, а не робити це як економія.


2

Для затемнення я використовую це: вікно -> уподобання -> java -> редактор -> зберегти дію -> встановіть прапорець для організованого імпорту (тут також є багато інших корисних речей, таких як форматування, зробити поля остаточними тощо. .). Тож коли я зберігаю свій файл, затемнення знімає імпорт usnessryry для мене. На мою думку, якщо вам щось не потрібно, то видаліть його (або нехай його видаляють затемненням).


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, не тестуючи збірку в локальному.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.