Czy jest jakiś powód, aby wyczyścić nieużywane importy w Javie, inny niż zmniejszenie bałaganu?


99

Czy istnieje dobry powód, aby unikać nieużywanych instrukcji importu w języku Java? Jak rozumiem, są one dostępne dla kompilatora, więc wiele nieużywanych importów nie będzie miało żadnego wpływu na skompilowany kod. Czy ma to na celu zmniejszenie bałaganu i uniknięcie konfliktów nazw?

(Pytam, ponieważ Eclipse ostrzega o nieużywanych importach, co jest trochę denerwujące, gdy tworzę kod, ponieważ nie chcę usuwać importu, dopóki nie będę pewien, że skończę projektować klasę).

Odpowiedzi:


86

Nie sądzę, aby problemy z wydajnością lub coś takiego były prawdopodobne, jeśli nie usuwasz importu.

Ale mogą wystąpić konflikty nazw, w rzadkich przypadkach, takich jak importowanie interfejsu listy.

W Eclipse zawsze możesz użyć skrótu (w zależności od systemu operacyjnego - Win: Ctrl + SHIFT + Oi Mac :) COMMAND + SHIFT + Odo organizowania importu. Następnie Eclipse czyści sekcję importu, usuwa wszystkie nieaktualne importy itp. Jeśli potrzebujesz ponownie importowanej rzeczy, eclipse doda je automatycznie podczas wypełniania instrukcji za pomocąCtrl + SPACE . Nie ma więc potrzeby trzymania nieużywanego kodu w klasie.

Jak zwykle nieużywany kod będzie rozpraszał Ciebie i inne osoby podczas czytania kodu, a pozostawienie czegoś w aktywnym kodzie, ponieważ może potrzebuję go później, jest zwykle postrzegane jako zła praktyka.


22
W rzeczywistości jest to Ctrl + Shift + O w systemie Windows.
Matt Ball

1
Ctrl + Shift + O na Linuksie dobrze. Prawdopodobnie to samo na BSD.
WhyNotHugo

2
Innym sposobem na przejście do akcji organizowania importu jest kliknięcie ctrl+3(przynajmniej na windwos), a następnie wpisanie importu. Jest oczywiście wolniejszy niż ctrl + shift + O, ale jest to sposób na szybkie znalezienie go (i wiele innych działań, które albo pamiętasz, albo po prostu próbujesz znaleźć), nawet jeśli nie pamiętasz konkretnego skrótu do tego.
epeleg

53

Jednym z nich byłoby to, że jeśli usuniesz klasę, do której odwołuje się import ze ścieżki klas, nie otrzymasz głupiego błędu kompilatora, który nie służył żadnemu celowi. I nie otrzymasz fałszywych alarmów podczas wyszukiwania „gdzie użyto”.

Innym (ale miałoby to bardzo specyficzny charakter) byłoby, gdyby nieużywany import powodował konflikty nazewnictwa z innym importem, powodując niepotrzebne używanie w pełni kwalifikowanych nazw.

Dodatek: Dziś serwer kompilacji zaczął nie działać poprawnie (nawet nie testował) z powodu braku pamięci. Działało dobrze przez zawsze, a zameldowania nie miały żadnych zmian w procesie kompilacji ani znaczących dodatków, które mogłyby to wyjaśnić. Po próbie zwiększenia ustawień pamięci (jest to uruchomienie 64-bitowej maszyny JVM na 64-bitowym systemie CentOS!) Do czegoś znacznie wykraczającego poza miejsce, w którym klienci mogliby się skompilować, sprawdzałem sprawdzenia jeden po drugim.

Wystąpił niewłaściwy import, którego użył i porzucił programista (użyli klasy, zaimportowali ją automatycznie, a następnie zdali sobie sprawę, że to pomyłka). Ten nieużywany import ściągnął całą oddzielną warstwę aplikacji, która podczas gdy IDE nie jest skonfigurowana do ich oddzielania, to proces kompilacji. Ten pojedynczy import przeciągnął tak wiele klas, że kompilator próbował skompilować się bez odpowiednich bibliotek zależnych w ścieżce klas, co spowodowało tak wiele problemów, że spowodowało błąd braku pamięci. Rozwiązanie tego problemu spowodowanego niewykorzystanym importem zajęło godzinę.


4
@Yishai, jeśli używasz Eclipse, zajrzyj do akcji zapisywania, które mogą normalizować kod źródłowy za każdym razem, gdy zapisujesz.
Thorbjørn Ravn Andersen

2
@EJP, chociaż nie wpływają one na wynikowy kod bajtowy, kompilator musi je rozwiązać, aby zrozumieć kod bajtowy, który musi utworzyć.
Yishai

3
@EJP, cały dodatek mówi o czasie kompilacji ("serwer kompilacji zaczął nie działać kompilacja").
Yishai

1
Nadal nie rozumiem, jak sam import może to wszystko spowodować?
Thorbjørn Ravn Andersen

1
@Yishai Przepraszam, ale nie wierzę w to. Błędnie to zdiagnozowałeś. Import nie powinien mieć takiego efektu, chyba że klasa była faktycznie używana. Instrukcja import informuje kompilator, w którym pakiecie znajduje się ta klasa. Kompilator próbuje kompilować niejawnie tylko wtedy, gdy potrzebuje informacji o typie tej klasy.
Markiz Lorne,

9

Z purystycznego punktu widzenia każda zależność jest „ograniczeniem” dla produktu i może w ten sposób później powodować problemy z konserwacją.

Na przykład załóżmy, że Twój program używa klasy com.XYZObjectPool i że później zdecydujesz się jej nie używać, ale nigdy nie usuniesz importu. Jeśli ktoś inny chce teraz utworzyć instancję org.WVYObjectPool i po prostu odwołać się do ObjectPool, nie otrzyma żadnego ostrzeżenia o tym, dopóki gdzieś nie pojawi się problem z rzutowaniem lub problemem z wywołaniem.

Nawiasem mówiąc, nie jest to nierealny scenariusz. Za każdym razem, gdy Eclipse pytał cię, którą konkretną wersję X chciałbyś zaimportować, i wybrałeś jedną z wielu pakietów, jest to scenariusz, w którym gdybyś miał tam import, mógłbyś dokonać złego wyboru, nie wiedząc o tym.

Tak czy inaczej, możesz poprosić Eclipse o ich wyczyszczenie


3

Ostrzeżenie? Poproś Eclipse o zautomatyzowane oczyszczenie ich za Ciebie. To właśnie robi IntelliJ. Jeśli jest wystarczająco inteligentny, aby cię ostrzec, powinien być wystarczająco inteligentny, aby je wyczyścić. Poleciłbym poszukać ustawienia Eclipse, aby powiedzieć mu, aby przestał być taką zrzędą i coś zrobił.


4
To zapisywanie działań. Osobiście podoba mi się to, że Eclipse zmienia twój kod tylko wtedy, gdy wyraźnie o to poprosiłeś.
Thorbjørn Ravn Andersen

1
@ Thorbjørn: Zgoda, zwłaszcza jeśli jest to klasa, z której przez jakiś czas przestałem korzystać, ale spodziewam się, że wkrótce ją ponownie dodam.
Donal Fellows

2
@Donal, cóż, do tego służy Ctrl-Space.
Thorbjørn Ravn Andersen

3

Ma to związek z przejrzystością programu przydatnego do konserwacji.

Gdybyś musiał utrzymywać program, przekonasz się, jak przydatne jest posiadanie jednego importu klasy w każdym wierszu.

Pomyśl o następującym scenariuszu:

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
     }
 }

Kiedy naprawiasz błędy lub konserwujesz fragment kodu (lub tylko go czytasz), bardzo pomocne dla czytelnika jest wiedzieć, do którego pakietu należą używane klasy. Użycie importu symboli wieloznacznych, jak pokazano powyżej, nie pomaga w tym celu.

Nawet mając IDE, nie chcesz najeżdżać kursorem lub przeskakiwać do deklaracji i zwracać, jest łatwiej, jeśli zrozumiesz pod względem funkcjonalności, od jakich innych pakietów i klas zależy bieżący kod.

Jeśli jest to projekt osobisty lub coś małego, to naprawdę nie ma to znaczenia, ale w przypadku czegoś większego, co musi być używane przez innych programistów (i utrzymywane przez lata), jest to MUSI MIEĆ.

Nie ma absolutnie żadnej różnicy w wydajności.


3

Do Twojej wiadomości, to mnie zaskoczyło, ponieważ nie sądziłem, że zorganizowany import faktycznie usunął nieużywany import, pomyślałem, że po prostu je posortował.

Automatyczne usuwanie importu podczas operacji zapisywania przysporzyło mi trochę zmartwień, gdy na przykład podczas tworzenia lub testowania masz problem i komentujesz jakiś kod, kiedy go zapisujesz, importy używane przez zakomentowaną sekcję kodu są usuwane. Czasami nie stanowi to problemu, ponieważ można cofnąć ( Ctrl+ Z) zmiany, ale innym razem nie jest to takie proste, jak można było wprowadzić inne zmiany. Miałem też problem polegający na tym, że kiedy odkomentowałem kod (wcześniej wykomentowałem, a następnie zapisałem, usuwając import dla tego kodu), automatycznie próbował odgadnąć importy, które były potrzebne i wybrał niewłaściwe (np. miałStringUtils klasę używaną i wybrał inny o tej samej nazwie z niewłaściwej biblioteki).

Wolę ręcznie organizować importowanie niż zapisywać.


2

W przypadku zaćmienia używam tego: okno -> preferencje -> java -> edytor -> zapisz akcję -> zaznacz pole wyboru organizowania importu (jest tam również wiele innych przydatnych rzeczy, takich jak formatowanie, ostateczne tworzenie pól i tak dalej. .). Kiedy więc zapisuję plik, zaćmienie usuwa za mnie nieudane importy. Moim zdaniem, jeśli czegoś nie potrzebujesz, usuń to (lub pozwól, aby zostało usunięte przez zaćmienie).


2

Możesz skomentować nieużywane instrukcje importu, a ostrzeżenia nie będą Ci przeszkadzać, ale możesz zobaczyć, co masz.


2
@DimaSan Właściwie tak: pytanie mówi , że nie chcę usuwać importu, dopóki nie jestem prawie pewien, że skończę projektować klasę.
The Vee

1

Nie ma to żadnego wpływu na wydajność, ale dla czytelności możesz sprawić, że będzie czysty. Usuwanie nieużywanego importu jest dość proste zarówno w Eclipse, jak i IntelliJ IDEA.

Zaćmienie

Windows / Linux -    Ctrl+ Shift+O

Mac -                        Cmd+ Shift+O

IntelliJ IDEA lub Android Studio

Windows / Linux -    Ctrl+ Alt+O

Mac -                        Cmd+ Alt+O


0

Czytałem gdzieś kilka lat temu, że każda importowana klasa byłaby ładowana w czasie wykonywania z klasą importującą. Zatem usunięcie nieużywanych, zwłaszcza całych pakietów, zmniejszyłoby obciążenie pamięci. Chociaż przypuszczam, że współczesne wersje javy sobie z tym radzą, więc prawdopodobnie nie jest to już powód.

Nawiasem mówiąc, w przypadku eclipse możesz użyć Ctrl+ Shift+ Odo organizowania importu, ale możesz także skonfigurować „odkurzacz”, który radzi sobie z takimi rzeczami (i wieloma innymi) za każdym razem, gdy zapisujesz plik java.


hmm .. zdziwiłbym się, gdyby takie było zachowanie. Wiem, że klasy nie są inicjowane (tj. wywoływanie statycznych inicjatorów) aż do pierwszego użycia, lub dopóki nie zostaną specjalnie zażądane przez niestandardowy program ładujący. ale jeśli przez „załadowany” masz na myśli tylko „wczytać do pamięci, ale nie przetworzyć”, jest to możliwe, chociaż wątpię w to.
Kip

właściwie, po głębszym przemyśleniu, test powinien być dość łatwy. skompiluj kod z nieużywanymi importami, a następnie użyj narzędzia do "dekompilacji" i sprawdź, czy nieużywane importy nadal istnieją, czy nie. jeśli nie, to albo są usuwane przez kompilator, albo są dostępne dla wygody programisty.
Kip

4
Gdzie na ziemi to przeczytałeś? Jest to całkowicie i całkowicie błędne i zawsze było. Każda klasa odwołuje się kod zostanie załadowany, nie w tym importu.
Markiz Lorne

0

Dla mnie jeden nieużywany import klasy w klasie kontrolera spowodował problem kompilacji w kompilacji Jenkinsa po usunięciu zaimportowanej klasy podczas czyszczenia kodu i dokonaniu usunięcia w git bez testowania kompilacji w lokalnym.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.