2008-10-09 4 views
76

Wäre es ein Unterschied in Bezug auf Overhead, einen Import zu schreiben, der alle Typen innerhalb eines Pakets lädt (import java.*); als nur ein spezifischer Typ (d. h. import java.lang.ClassLoader)? Wäre der zweite besser geeignet als der andere?Paket importieren. * Vs. Import package.SpecificType

+1

Siehe http://stackoverflow.com/questions/1983435/eclipse-java-is-it-harmful-to-import-java-namespace/1984499#1984499 und http://stackoverflow.com/questions/2141144/ java-import-can-be-slowly – skaffman

Antwort

72

Es gibt keine Leistungs- oder Gemeinkosten für den Import. * Vs Importieren bestimmter Typen. Ich halte es jedoch für eine bewährte Methode, den Import niemals zu verwenden. * Mein Hauptgrund dafür ist, dass ich die Dinge geradlinig, sauber und mit so wenig Zweideutigkeiten wie möglich halte, und ich denke, mit einem * Import verlieren Sie das .

+0

Eigentlich habe ich verstanden, das Import-Paket zu vermeiden. * als eine Optimierung für den Compiler, weil es dem Compiler ermöglicht, die Klassen-Datei besser nachzusehen, wenn die aktuelle Datei kompiliert wird. –

+2

Zweifel, dass es irgendwelche Optimierungsprobleme mit diesem geben wird .. Außer Namenskonflikten, wo Sie sie leicht mit bestimmten Importanweisungen vermeiden können. Selbst wenn Sie zu faul sind, alle Importe einzugeben, werden moderne IDE's es für Sie tun ... – Thihara

8

Ein guter Grund, niemals den Import xxx zu verwenden. * Ist eine klare Vision von dependencies.

Sie können schneller wissen, dass Sie eine bestimmte Klasse eines anderen Pakets verwenden, da es direkt am Anfang der Quelldatei aufgeführt wird.

+11

Wenn Ihre Liste von Importen 70 oder 200 Zeilen lang ist, haben Sie keine klare Vision von Abhängigkeiten mehr. –

+8

Aber das ist nicht die Schuld der Import-Aussagen, es ist deins. – whiskeysierra

92

Werfen Sie einen Blick auf die Java-API, und Sie werden viele Klassen und Schnittstellen mit demselben Namen in verschiedenen Paketen sehen.

Zum Beispiel:

java.lang.reflect.Array 
java.sql.Array 

Also, wenn Sie importieren java.lang.reflect.* und java.sql.* es eine Kollision auf dem Array-Typ hat, und müssen sie vollständig in Ihrem Code qualifizieren.

Durch den Import bestimmter Klassen sparen Sie sich diesen Aufwand.

+6

Namenskonflikte! Das habe ich übersehen. +1 an Sie – VonC

+0

@Chris Was bewirkt die Verwendung von 'import a.b. *' zur Kompilierzeit? – saurabheights

+1

@saurabheights Kümmert es uns? Kein Snark beabsichtigt. Kompilierzeit ist im Allgemeinen kein Entwicklungsanliegen, es sei denn, es wird absurd. Es ist die Laufzeit, die uns beschäftigt. –

6

Nachdem ich nach weiteren Informationen gesucht habe, bin ich auf diese Website gestoßen, wo sie sehr gut erklärt wird. Import issue und Does using * in an import statement affect performance?.

Gibt es Effizienzprobleme zwischen diesen beiden Stilen? Möglicherweise, aber da Import-Deklarationen nichts in Ihr Programm importieren, ist der Unterschied sehr gering. Denken Sie daran, dass es einen impliziten Import java.lang. * An der Spitze Ihrer Kompilierungseinheiten gibt und java.lang in JDK 1.2.2 75 Klassen und Schnittstellen enthält. Ein Experiment, bei dem ein künstliches Beispiel verwendet wurde, eines mit tausenden Klassennamensverwendungen, die nachgeschlagen werden müssen, zeigte eine vernachlässigbare Änderung der Kompilierungsgeschwindigkeit. Daher sollte die Kompilierungsleistung wahrscheinlich nicht als ein Faktor angesehen werden, wenn ein Format einem anderen gegenübergestellt wird.

Es gibt einen letzten Winkel von Interesse für Importdeklarationen. Angenommen, Sie verwenden eine innere Klasse:

package P; 

public class A { 
    public static class B {} 
} 

Wenn Sie eine von einer anderen Übersetzungseinheit zugreifen möchten, sagen Sie:

import P.*; 

oder: Import P.A; Aber wenn Sie B ohne Qualifikation zugreifen möchten, müssen Sie sagen:

import P.A.*; 

oder: Import P.A.B; Der erste von diesen stellt verfügbare Typen innerhalb der Klasse A im Paket P zur Verfügung. Der zweite stellt nur den Typ B in Klasse A in Paket P zur Verfügung.

3

Ich neige dazu, zu verwenden, was auch immer der IDE-Standard ist. Ich finde, dass es sich nicht lohnt, sich darüber Gedanken zu machen, da es keine Auswirkungen auf die Performance hat und die Überprüfung von Abhängigkeiten mit einer Vielzahl von Tools gehandhabt werden kann.

2

Die Importe sind auf Bytecode-Ebene nicht wichtig, daher sollte es keine Laufzeitdifferenz geben.

Ich finde es am besten: a) Seien Sie explizit durch die Auflistung aller Importe b) Lassen Sie Ihre IDE es verwalten. Alle wichtigen IDEs können Ihre Importe automatisch aktualisieren, sortieren und vervollständigen.

Ich habe a) gefunden, um ein paar Mal nützlich zu sein, wenn man manuelle Umpackung außerhalb des Kontexts eines In-IDE-Refactoring macht. Wie zum Beispiel, wenn Marketing den Namen Ihres Produktes ändert und entscheidet, dass alle Ihre Pakete den Namen ändern sollten.

22

Das ist eigentlich ein sehr schlechtes Problem.

Angenommen, Sie

schreiben
import a.*; 
import b.*; 
... 
Foo f; 

und Klasse Foo existiert ein im Paket.

Jetzt checken Sie Ihren perfekten Kompilierungscode ein und sechs Monate später fügt jemand Klasse Foo zu Paket b hinzu. (Vielleicht ist es eine Third Party Lib, die Klassen in der neuesten Version hinzugefügt hat).

Poof! Jetzt verweigert der Code die Kompilierung.

Nie Verwendung Import-on-Demand. Es ist böse!

Weitere Informationen finden Sie unter http://javadude.com/articles/importondemandisevil.html.

RE Leistung:

import a.*; 

vs

import a.X; 

macht keinen Unterschied zur Laufzeit. Der Compiler stellt die aufgelösten Klassennamen in die generierten .class-Dateien fest.

+0

Ich wollte einen Link zu Ihrem Artikel veröffentlichen (den ich gestern gelesen habe), aber ich dachte, Sie würden es wahrscheinlich selbst machen. :) –

+7

Es ist nicht "böse" *, es hat nur einen Nachteil, den Sie beachten sollten. –

+0

Nein - es ist eine böse Eigenschaft, die Bruch erlaubt, wenn Code zu externen Bibliotheken hinzugefügt wird. –

9

Ansicht von Minderheit: in meinem Code Ich neige dazu, Tonnen von Klassen aus ein paar Paketen zusammen mit ein paar ungeraden Klassen hier und da zu verwenden. Ich möchte meine Importliste klein halten, damit ich auf einen Blick sehen kann, was passiert. Um dies zu tun, setze ich den Schwellenwert auf 4 Klassen. Darüber hinaus verwendet Eclipse * für meinen Code. Ich finde, dass dies meine Paket-Importe lesbar hält, und ich neige dazu, sie als die erste Sache zu bezeichnen, die ich mache, wenn ich auf eine Klasse schaue, um die Frage zu beantworten: Wem spricht es?

In Bezug auf Name Kollision: Wie sind die Chancen, dass Sie vier oder mehr Klassen aus zwei Paketen importieren, die konkurrierende Klassennamen haben? Wenn es mehr als 10% der Zeit ist, sollten Sie die Anzahl der Pakete berücksichtigen, auf die Ihre Klasse angewiesen ist (z. B. um sie in kleinere Klassen umzuwandeln).

+3

stimme ich zu; Ich habe in der Praxis immer nur auf die AWT-List vs. util List-Kollision gestoßen, und dann füge ich normalerweise nur einen bestimmten Import für den einen hinzu, den ich möchte, normalerweise die Sammlung. –

+2

@Software Monkey, wahr, dass. Der springende Punkt von Paketen ist, dass sie Klassen sind, die zusammenhalten, was der Grund für den Import ist. –

0

Es ist mehr eine gute Kodierungspraxis, da jeder, der Ihren Code liest, sofort weiß, welche Klassen von einer bestimmten Klasse verwendet werden, indem Sie einfach den Importblock an der Spitze der Datei betrachten, während man graben müsste Sie haben Platzhalter verwendet.

+2

Nein werden sie nicht; Sie werden alle Klassen kennen, die jemals verwendet wurden - einige wurden möglicherweise entfernt, wenn der Code älter wird. –

+1

Moderne IDEs wie Eclipse scheinen einen guten Job zu machen, unbenutzte Importe zu markieren und den vollständig qualifizierten Klassennamen anzuzeigen, wenn man den Mauszeiger über einen Klassennamen bewegt. Ich bin also nicht sicher, wie relevant das Argument "muss graben" ist. Andererseits habe ich auch meine IDE "eingeklappt" die Importe so dass sie mir nicht in die Quere kommen, deshalb ist es mir normalerweise egal ob sie Wildcard Imports sind die speziell benannten Klassen. – iX3

3

Wenn Sie mehr als 20 Klassen aus demselben Paket importieren, verwenden Sie besser xxx importieren. *. "Clean Code" spricht sich dafür aus, das gesamte Paket ebenfalls zu importieren.