630 Stimmen

Typ Liste vs. Typ ArrayList in Java

(1) List<?> myList = new ArrayList<?>();

(2) ArrayList<?> myList = new ArrayList<?>();

Ich verstehe, dass mit (1), Implementierungen der Liste Schnittstelle ausgetauscht werden kann. Es scheint, dass (1) typischerweise in einer Anwendung verwendet wird, unabhängig von der Notwendigkeit (ich selbst verwende dies immer).

Ich frage mich, ob jemand (2) verwendet?

Wie oft (und kann ich bitte ein Beispiel bekommen) ist es tatsächlich erforderlich, (1) gegenüber (2) zu bevorzugen (d.h. wo (2) nicht ausreichen würde..aside Kodierung auf Schnittstellen y beste Praktiken usw.)

14voto

mazatwork Punkte 1215

Ich verwende (2), wenn der Code der "Eigentümer" der Liste ist. Dies gilt zum Beispiel für nur lokal verfügbare Variablen. Es gibt keinen Grund für die Verwendung des abstrakten Typs List 代わりに ArrayList . Ein weiteres Beispiel zur Verdeutlichung des Eigentums:

public class Test {

    // This object is the owner of strings, so use the concrete type.
    private final ArrayList<String> strings = new ArrayList<>();

    // This object uses the argument but doesn't own it, so use abstract type.
    public void addStrings(List<String> add) {
        strings.addAll(add);
    }

    // Here we return the list but we do not give ownership away, so use abstract type. This also allows to create optionally an unmodifiable list.
    public List<String> getStrings() {
        return Collections.unmodifiableList(strings);
    }

    // Here we create a new list and give ownership to the caller. Use concrete type.
    public ArrayList<String> getStringsCopy() {
        return new ArrayList<>(strings);
    }
}

9voto

Pavel Vyazankin Punkte 1430
(3) Collection myCollection = new ArrayList<?>();

Ich verwende dies normalerweise. Und nur Wenn ich Listenmethoden benötige, werde ich List. Dasselbe gilt für ArrayList. Sie können immer zu mehr "schmalen" Schnittstelle wechseln, aber Sie können nicht zu mehr "breit" wechseln.

9voto

True Soft Punkte 8496

Ich glaube, dass die Leute, die (2) verwenden, nicht wissen, was die Liskov-Substitutionsprinzip oder die Prinzip der Abhängigkeitsinversion . Oder sie müssen wirklich die ArrayList .

9voto

raudi Punkte 1699

Es gibt tatsächlich Fälle, in denen (2) nicht nur bevorzugt wird, sondern zwingend erforderlich ist, und ich bin sehr überrascht, dass dies hier niemand erwähnt hat.

Serialisierung!

Wenn Sie eine serialisierbare Klasse haben und diese eine Liste enthalten soll, dann müssen Sie das Feld als einen konkreten und serialisierbaren Typ deklarieren, wie ArrayList weil die List Schnittstelle erweitert nicht java.io.Serializable

Offensichtlich brauchen die meisten Menschen keine Serialisierung und vergessen dies.

Ein Beispiel:

public class ExampleData implements java.io.Serializable {

// The following also guarantees that strings is always an ArrayList.
private final ArrayList<String> strings = new ArrayList<>();

8voto

akhil_mittal Punkte 20953

Von den folgenden zwei:

(1) List<?> myList = new ArrayList<?>();
(2) ArrayList<?> myList = new ArrayList<?>();

Die erste ist im Allgemeinen vorzuziehen. Da Sie die Methoden von List Schnittstelle zu verwenden, bietet es Ihnen die Freiheit, eine andere Implementierung von List z.B.. LinkedList in Zukunft. Sie sind also von der konkreten Umsetzung entkoppelt. Nun gibt es zwei Punkte, die erwähnenswert sind:

  1. Wir sollten immer für Schnittstellen programmieren. Mehr aquí .
  2. Sie werden am Ende fast immer mit ArrayList über LinkedList . Mehr aquí .

Ich frage mich, ob jemand (2)

Ja, manchmal (eher selten). Wenn wir Methoden benötigen, die Teil der Implementierung von ArrayList aber nicht Teil der Schnittstelle List . Zum Beispiel ensureCapacity .

Und wie oft (und kann ich bitte ein Beispiel bekommen) kommt es vor, dass die Situation tatsächlich die Verwendung von (1) gegenüber (2)

Fast immer ziehen Sie Option (1) vor. Dies ist ein klassisches Entwurfsmuster in der OOP, bei dem Sie immer versuchen, Ihren Code von der spezifischen Implementierung zu entkoppeln und auf die Schnittstelle zu programmieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X