Frage

PMD würde einen Verstoß melden für:

ArrayList<Object> list = new ArrayList<Object>();

Die Verletzung war „Vermeiden Sie Implementierungstypen wie‚Arraylist‘verwendet; die Schnittstelle verwenden, anstatt“.

Die folgende Zeile würde korrigieren Sie den Verstoß:

List<Object> list = new ArrayList<Object>();

Warum sollte diese mit List statt ArrayList verwendet werden?

War es hilfreich?

Lösung

Schnittstellen über konkrete Typen zu verwenden ist der Schlüssel für eine gute Kapselung und für lose Kopplung Code.

Es ist auch eine gute Idee, diese Praxis zu folgen, wenn Sie Ihre eigenen APIs zu schreiben. Wenn Sie das tun, finden Sie später, dass es einfacher ist, Unit-Tests, um Ihren Code hinzufügen (Mocking Techniken) und die zugrunde liegende Implementierung zu ändern, wenn in der Zukunft benötigt werden.

Hier ist ein rel="noreferrer"> auf der Thema.

Hoffe, es hilft!

Andere Tipps

Dies ist bevorzugt, weil Sie Ihren Code aus der Umsetzung der Liste entkoppeln. Mit Hilfe der Schnittstelle können Sie bequem die Implementierung ändern, Arraylist in diesem Fall in einer anderen Liste Implementierung ohne den Rest des Codes zu ändern, solange es nur Methoden in Liste definiert verwendet.

Generell Ich bin damit einverstanden, dass Schnittstelle von der Implementierung Entkopplung ist eine gute Sache und wird der Code leichter zu halten.

Es gibt jedoch Ausnahmen, die Sie berücksichtigen müssen. Zugriff auf Objekte über Schnittstellen fügt eine zusätzliche Schicht von Dereferenzierung, die Ihr Code langsamer machen.

Für Interesse lief ich ein Experiment, das zehn Milliarden sequenzielle Zugriffe auf eine 1 Million Länge Arraylist erzeugt. Auf meinem 2,4 GHz MacBook, nahm die Arraylist durch eine Liste Schnittstelle Zugriff auf 2,10 Sekunden im Durchschnitt, wenn es vom Typ Arraylist deklariert es im Durchschnitt 1,67 Sekunden dauerte.

Wenn Sie mit großen Listen arbeiten, tief im Innern einer inneren Schleife oder häufig aufgerufene Funktion, dann ist dies etwas zu prüfen.

Arraylist und LinkedList sind zwei Implementierungen einer Liste, die eine geordnete Sammlung von Gegenständen ist. Logic-weise es spielt keine Rolle, ob Sie eine Arraylist oder ein LinkedList verwenden, so sollten Sie den Typ nicht einschränken, dass sein.

Dies steht im Gegensatz zu sagen, Sammlung und List, die verschiedenen Dinge sind (List impliziert Sortierung, Sammlung nicht).

Auch für lokale Variablen, mit der Schnittstelle über die konkrete Klasse hilft. Sie können eine Methode aufrufen am Ende, die außerhalb der Schnittstelle ist, und dann ist es schwierig, die Umsetzung der Liste, wenn nötig zu ändern. Auch ist es am besten, die am wenigsten spezifische Klasse oder Schnittstelle in einer Erklärung zu verwenden. Wenn das Element verwenden, um keine Rolle spielt, eine Sammlung statt einer Liste. Das gibt den Code ein Maximum an Flexibilität.

Eigenschaften Ihrer Klassen / Schnittstellen sollten über Schnittstellen ausgesetzt werden, weil es Ihren Klassen einen Vertrag von Verhalten gibt, zu verwenden, unabhängig von der Implementierung.

Allerdings ...

In lokalen Variablendeklarationen, macht es wenig Sinn, dies zu tun:

public void someMethod() {
List theList = new ArrayList();
//do stuff with the list
}

Wenn sie eine lokale Variable, verwenden Sie einfach den Typen. Es ist immer noch implizit auf seine entsprechenden Schnittstelle upcastable und Ihre Methoden sollten hoffentlich die Schnittstellentypen für seine Argumente akzeptieren, aber für lokale Variablen, macht es absolut Sinn, die Umsetzung Typen als Container zu verwenden, nur für den Fall, dass Sie die Implementierungs- tun müssen spezifische Funktionalität.

In der Regel für Ihre Codezeile macht es keinen Sinn mit Schnittstellen zu stören machen. Aber wenn wir über APIs sprechen gibt es einen wirklich guten Grund. Ich habe kleine Klasse

class Counter {
    static int sizeOf(List<?> items) {
        return items.size();
    }
}

In diesem Fall ist die Nutzung der Schnittstelle erforderlich. Weil ich will, Größe zählen von alle möglichen Implementierung einschließlich meiner eigenen Brauch. class MyList extends AbstractList<String>....

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top