Gibt es einen Grund, nicht verwendete Importe in Java zu bereinigen, außer die Unordnung zu verringern?

99

Gibt es einen guten Grund, nicht verwendete Importanweisungen in Java zu vermeiden? Soweit ich weiß, sind sie für den Compiler da, sodass viele nicht verwendete Importe keine Auswirkungen auf den kompilierten Code haben. Ist es nur, um Unordnung zu reduzieren und Namenskonflikte auf der ganzen Linie zu vermeiden?

(Ich frage, weil Eclipse eine Warnung vor nicht verwendeten Importen ausgibt. Dies ist ärgerlich, wenn ich Code entwickle, da ich die Importe erst entfernen möchte, wenn ich ziemlich sicher bin, dass ich mit dem Entwerfen der Klasse fertig bin.)

Pennen
quelle

Antworten:

86

Ich denke nicht, dass Leistungsprobleme oder ähnliches wahrscheinlich sind, wenn Sie die Importe nicht entfernen.

Es kann jedoch zu Namenskonflikten kommen, in seltenen Fällen wie beim Importieren der Listenschnittstelle.

In Eclipse können Sie immer eine Verknüpfung verwenden (abhängig von Betriebssystem - Win: Ctrl + SHIFT + Ound Mac :) COMMAND + SHIFT + O, um die Importe zu organisieren. Eclipse bereinigt dann den Importabschnitt und entfernt alle veralteten Importe usw. Wenn Sie ein importiertes Objekt erneut benötigen, fügt Eclipse diese automatisch hinzu, während Sie die Anweisung mit vervollständigen Ctrl + SPACE. Es ist also nicht erforderlich, nicht verwendeten Code in Ihrer Klasse zu behalten.

Wie immer lenkt unbenutzter Code Sie und andere Personen ab, während Sie den Code lesen und etwas in Ihrem aktiven Code belassen, da ich ihn möglicherweise später benötige. Dies wird meistens als schlechte Praxis angesehen.

Janusz
quelle
22
Es ist eigentlich Strg + Umschalt + O unter Windows.
Matt Ball
1
Strg + Umschalt + O unter Linux gut. Wahrscheinlich das gleiche bei BSD.
WhyNotHugo
2
Eine andere Möglichkeit, die Aktion zum Importieren von Importen zu erreichen, besteht darin, auf ctrl+3(zumindest auf windwos) zu klicken und dann Importe einzugeben. Es ist offensichtlich langsamer als Strg + Umschalt + O, aber es ist eine Möglichkeit, es schnell zu finden (und viele andere Aktionen, an die Sie sich erinnern oder die Sie nur zu finden versuchen), selbst wenn Sie sich nicht an die spezielle Verknüpfung dafür erinnern.
Epeleg
53

Wenn Sie die Klasse, auf die durch den Import verwiesen wird, aus dem Klassenpfad entfernen, erhalten Sie keinen dummen Compilerfehler, der keinen Zweck erfüllt. Und Sie erhalten keine Fehlalarme, wenn Sie eine Suche nach Verwendungszweck durchführen.

Eine andere Möglichkeit (dies wäre jedoch sehr spezifisch) wäre, wenn der nicht verwendete Import Namenskonflikte mit einem anderen Import hätte, sodass Sie unnötig vollqualifizierte Namen verwenden müssten.

Nachtrag: Heute hat der Build-Server begonnen, die Kompilierung (nicht einmal den Testlauf) mit einem Speicherfehler fehlzuschlagen. Es lief für immer einwandfrei und die Check-Ins hatten keine Änderungen am Erstellungsprozess oder wesentliche Ergänzungen, die dies erklären könnten. Nachdem ich versucht hatte, die Speichereinstellungen (dies führt eine 64-Bit-JVM unter einem 64-Bit-CentOS aus!) Auf etwas zu erhöhen, das weit über den Kompilierungsmöglichkeiten der Clients hinausgeht, untersuchte ich die Checkins nacheinander.

Es gab einen falschen Import, den ein Entwickler verwendet und abgebrochen hatte (sie verwendeten die Klasse, importierten sie automatisch und stellten dann fest, dass es sich um einen Fehler handelte). Durch diesen nicht verwendeten Import wurde eine separate Ebene der Anwendung abgerufen, die zwar nicht für die Trennung der IDE konfiguriert ist, der Erstellungsprozess jedoch ausgeführt wird. Dieser einzelne Import zog so viele Klassen mit sich, dass der Compiler versuchte, zu kompilieren, ohne die relevanten abhängigen Bibliotheken im Klassenpfad zu haben, so dass dies so viele Probleme verursachte, dass es zu einem Speicherfehler kam. Es dauerte eine Stunde, um dieses Problem zu lösen, das durch einen nicht verwendeten Import verursacht wurde.

Yishai
quelle
4
@Yishai, wenn Sie Eclipse verwenden, schauen Sie in Aktionen speichern, die den Quellcode bei jedem Speichern normalisieren können.
Thorbjørn Ravn Andersen
2
@EJP, obwohl sie den resultierenden Bytecode nicht beeinflussen, muss der Compiler sie auflösen, um den zu erstellenden Bytecode zu verstehen.
Yishai
3
@EJP, im gesamten Anhang geht es um die Kompilierungszeit ("Build-Server hat die Kompilierung fehlgeschlagen").
Yishai
1
Ich verstehe immer noch nicht, wie der Import allein all dies verursachen könnte?
Thorbjørn Ravn Andersen
1
@ Yishai Sorry, aber ich glaube es nicht. Sie haben dies falsch diagnostiziert. Der Import sollte keinen solchen Effekt haben, es sei denn, die Klasse wurde tatsächlich verwendet. Die import-Anweisung teilt dem Compiler lediglich mit, in welchem ​​Paket sich diese Klasse befindet. Der Compiler versucht nur dann implizit zu kompilieren, wenn er Typinformationen zu dieser Klasse benötigt.
Marquis von Lorne
9

Aus puristischer Sicht ist jede Abhängigkeit eine "Einschränkung" des Produkts und kann daher später zu Wartungsproblemen führen.

Angenommen, Ihr Programm verwendet die Klasse com.XYZObjectPool und Sie entscheiden sich später, sie nicht zu verwenden, aber den Import niemals zu entfernen. Wenn jemand anderes jetzt org.WVYObjectPool instanziieren und einfach auf ObjectPool verweisen möchte, erhält er keine Warnung, bis irgendwo auf der ganzen Linie ein Casting- oder Aufrufproblem auftritt.

Dies ist übrigens kein unrealistisches Szenario. Jedes Mal, wenn Sie von Eclipse gefragt wurden, welche bestimmte Version von X Sie importieren möchten, und Sie eine aus vielen Paketen ausgewählt haben, ist dies ein Szenario, in dem Sie, wenn Sie den Import dort hatten, möglicherweise die falsche Wahl getroffen haben, ohne davon zu wissen.

In beiden Fällen können Sie Eclipse bitten, diese für Sie zu bereinigen

Uri
quelle
3

Warnung? Bitten Sie Eclipse, diese automatisch für Sie zu bereinigen. Das macht IntelliJ. Wenn es klug genug ist, um Sie zu warnen, sollte es klug genug sein, um sie zu bereinigen. Ich würde empfehlen, nach einer Eclipse-Einstellung zu suchen, um zu sagen, dass sie aufhören soll, so ein Nörgler zu sein, und etwas tun soll.

Duffymo
quelle
4
Das ist Speichern von Aktionen. Persönlich gefällt mir, dass Eclipse Ihren Code nur ändert, wenn Sie ausdrücklich danach gefragt haben.
Thorbjørn Ravn Andersen
1
@ Thorbjørn: Einverstanden, besonders wenn es sich um eine Klasse handelt, die ich für ein bisschen nicht mehr benutze, die ich aber voraussichtlich in Kürze wieder hinzufügen werde.
Donal Fellows
2
@Donal, na ja, dafür ist Ctrl-Space da.
Thorbjørn Ravn Andersen
3

Dies hat mit der Klarheit des Programms zu tun, das für die Wartung nützlich ist.

Wenn Sie ein Programm warten mussten, werden Sie feststellen, wie nützlich es ist, einen einzelnen Klassenimport pro Zeile durchzuführen.

Denken Sie an das folgende Szenario:

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

Wenn Sie Fehler beheben oder Code beibehalten (oder nur lesen), ist es für den Leser sehr hilfreich zu wissen, zu welchem ​​Paket die verwendeten Klassen gehören. Die Verwendung des Platzhalterimports wie oben gezeigt hilft zu diesem Zweck nicht.

Selbst mit einer IDE möchten Sie nicht schweben oder zur Deklaration springen und zurückkehren. Es ist einfacher, wenn Sie in Bezug auf die Funktionalität verstehen, von welchen anderen Paketen und Klassen der aktuelle Code abhängt.

Wenn dies für ein persönliches Projekt oder etwas Kleines ist, spielt es wirklich keine Rolle, aber für etwas Größeres, das von anderen Entwicklern verwendet werden muss (und über die Jahre gewartet wird), ist dies ein MUSS.

Es gibt absolut keinen Leistungsunterschied mit irgendwelchen.

OscarRyz
quelle
3

Zu Ihrer Information, das hat mich überrascht, da ich nicht dachte, dass das Organisieren von Importen tatsächlich nicht verwendete Importe entfernt, ich dachte, es würde sie nur sortieren.

Das automatische Entfernen von Importen während eines Speichervorgangs verursachte mir einige Sorgen, wenn Sie beispielsweise während der Entwicklung oder beim Testen ein Problem haben und Code auskommentieren. Wenn Sie ihn speichern, werden die vom auskommentierten Codeabschnitt verwendeten Importe entfernt. Manchmal ist dies kein Problem, da Sie die Änderungen rückgängig machen ( Ctrl+ Z) können, aber manchmal ist es nicht so einfach, wie Sie möglicherweise andere Änderungen vorgenommen haben. Ich hatte auch ein Problem, bei dem beim Auskommentieren des Codes (ich habe ihn zuvor auskommentiert und dann gespeichert und damit die Importe für diesen Code entfernt) automatisch versucht wurde, die benötigten Importe zu erraten und die falschen zu finden (z. B. glaube ich Es wurde eine StringUtilsKlasse verwendet, die eine andere mit demselben Namen aus der falschen Bibliothek auswählte.

Ich bevorzuge es, Importe manuell zu organisieren, anstatt sie als Speicheraktion zu verwenden.

John
quelle
2

Für Eclipse benutze ich Folgendes: Fenster -> Einstellungen -> Java -> Editor -> Aktion speichern -> Aktivieren Sie das Kontrollkästchen zum Organisieren von Importen (es gibt dort auch viele andere nützliche Dinge, wie Formatieren, Finalisieren von Feldern usw.). .). Wenn ich also meine Datei speichere, entfernt Eclipse die Unessacry-Importe für mich. Wenn Sie meiner Meinung nach etwas nicht benötigen, entfernen Sie es (oder lassen Sie es durch Eclipse entfernen).

Kukudas
quelle
2

Sie könnten die nicht verwendeten Importanweisungen auskommentieren und die Warnungen werden Sie nicht stören, aber Sie können sehen, was Sie hatten.

Sharon
quelle
2
@DimaSan Eigentlich schon: Die Frage besagt, dass ich die Importe erst entfernen möchte, wenn ich mir ziemlich sicher bin, dass ich mit dem Entwerfen der Klasse fertig bin.
The Vee
1

Es gibt keine Auswirkungen auf die Leistung, aber aus Gründen der Lesbarkeit können Sie es sauber machen. Das Entfernen nicht verwendeter Importe ist sowohl in Eclipse als auch in IntelliJ IDEA recht einfach.

Finsternis

Windows / Linux -    Ctrl+ Shift+O

Mac -                        Cmd+ Shift+O

IntelliJ IDEA oder Android Studio

Windows / Linux -    Ctrl+ Alt+O

Mac -                        Cmd+ Alt+O

Madan Sapkota
quelle
0

Ich habe vor einigen Jahren irgendwo gelesen, dass jede importierte Klasse zur Laufzeit mit der importierenden Klasse geladen wird. Das Entfernen nicht verwendeter, insbesondere ganzer Pakete würde den Speicheraufwand verringern. Obwohl ich vermute, dass moderne Versionen von Java sich damit befassen, ist dies wahrscheinlich kein Grund mehr.

Übrigens können Sie mit Eclipse Ctrl+ Shift+ verwenden O, um Importe zu organisieren, aber Sie können auch einen "Cleaner" konfigurieren, der sich jedes Mal, wenn Sie eine Java-Datei speichern, mit solchen Dingen (und vielen anderen) befasst.

Michael Zilbermann
quelle
hmm .. ich wäre überrascht, wenn das das Verhalten wäre .. ich weiß, dass Klassen erst bei der ersten Verwendung oder bis sie speziell von einem benutzerdefinierten Loader angefordert werden, initialisiert werden (dh die statischen Initialisierer aufrufen). aber wenn mit "geladen" nur "in den Speicher einlesen, aber nicht verarbeitet" gemeint ist, ist dies möglich, obwohl ich es bezweifle.
Kip
Nach weiteren Überlegungen sollte es eigentlich ziemlich einfach zu testen sein. Kompilieren Sie Code mit nicht verwendeten Importen, verwenden Sie dann ein "Dekompilierungs" -Tool und prüfen Sie, ob die nicht verwendeten Importe noch vorhanden sind oder nicht. Wenn nicht, werden sie entweder vom Compiler entfernt oder sind nur zur Vereinfachung für den Programmierer da.
Kip
4
Wo um alles in der Welt hast du das gelesen? Es ist völlig falsch und war es schon immer. Jede Klasse, auf die der Code verweist, wird geladen, ohne Importe.
Marquis von Lorne
0

Für mich verursachte ein nicht verwendeter Klassenimport in einer Controller-Klasse ein Kompilierungsproblem in Jenkins Build, nachdem ich die importierte Klasse während der Codebereinigung gelöscht und das Löschen in Git festgeschrieben hatte, ohne einen Build in Local zu testen.

Aakash Kedia
quelle