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.)

4voto

Xar-e-ahmer Khan Punkte 1504

Liste ist eine Schnittstelle. Sie hat keine Methoden. Wenn Sie eine Methode auf eine List-Referenz aufrufen, ruft sie in beiden Fällen die Methode von ArrayList auf.

Und für die Zukunft können Sie ändern List obj = new ArrayList<> zu List obj = new LinkList<> oder andere Typen, die die Schnittstelle auflisten .

3voto

toxicafunk Punkte 396

Jemand hat diese Frage erneut gestellt (Duplikat), was mich dazu veranlasst hat, mich mit diesem Thema etwas eingehender zu beschäftigen.

public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    list.add("a");
    list.add("b");

    ArrayList<String> aList = new ArrayList<String>();
    aList.add("a");
    aList.add("b");

}

Wenn wir einen Bytecode-Viewer verwenden (ich habe http://asm.ow2.org/eclipse/index.html ), dann sehen Sie das Folgende (nur Listeninitialisierung und Zuweisung) für unsere Liste Schnipsel:

   L0
    LINENUMBER 9 L0
    NEW ArrayList
    DUP
    INVOKESPECIAL ArrayList.<init> () : void
    ASTORE 1
   L1
    LINENUMBER 10 L1
    ALOAD 1: list
    LDC "a"
    INVOKEINTERFACE List.add (Object) : boolean
    POP
   L2
    LINENUMBER 11 L2
    ALOAD 1: list
    LDC "b"
    INVOKEINTERFACE List.add (Object) : boolean
    POP

und für alist :

   L3
    LINENUMBER 13 L3
    NEW java/util/ArrayList
    DUP
    INVOKESPECIAL java/util/ArrayList.<init> ()V
    ASTORE 2
   L4
    LINENUMBER 14 L4
    ALOAD 2
    LDC "a"
    INVOKEVIRTUAL java/util/ArrayList.add (Ljava/lang/Object;)Z
    POP
   L5
    LINENUMBER 15 L5
    ALOAD 2
    LDC "b"
    INVOKEVIRTUAL java/util/ArrayList.add (Ljava/lang/Object;)Z
    POP

Der Unterschied ist Liste endet mit einem Anruf INVOKEINTERFACE während aList ruft auf. INVOKEVIRTUAL . Gemäß der Referenz des Bycode Outline Plugin,

invokeinterface wird verwendet, um eine Methode aufzurufen, die innerhalb einer Java Schnittstelle

während invokevirtual

ruft alle Methoden mit Ausnahme der Schnittstellenmethoden auf (diese verwenden invokeinterface), statische Methoden (die invokestatic verwenden) und die wenigen Spezialfälle, die von invokespecial behandelt werden.

Zusammenfassend lässt sich sagen, dass invokevirtual pops objectref vom Stapel, während für invokeinterface

holt der Interpreter 'n' Elemente vom Operandenstapel, wobei 'n' ein 8-Bit-Parameter ohne Vorzeichen ist Integer-Parameter aus dem Bytecode ist. Das erste dieser Elemente ist objectref, ein Verweis auf das Objekt, dessen Methode gerade aufgerufen wird.

Wenn ich das richtig verstanden habe, besteht der Unterschied im Wesentlichen darin, wie jede Methode die Daten abruft. objectref .

2voto

Hans Westerbeek Punkte 5447

Der einzige Fall, der mir bekannt ist, in dem (2) kann sein besser ist, wenn man GWT verwendet, weil es den Fußabdruck der Anwendung reduziert (nicht meine Idee, aber das Google Web Toolkit Team sagt das). Aber für normale Java läuft innerhalb der JVM (1) ist wahrscheinlich immer besser.

1voto

extraneon Punkte 22810

Ich würde sagen, dass 1 vorzuziehen ist, es sei denn

  • Sie sind von der Implementierung des optionalen Verhaltens* in ArrayList abhängig; in diesem Fall ist die explizite Verwendung von ArrayList eindeutiger
  • Sie werden die ArrayList in einem Methodenaufruf verwenden, der ArrayList benötigt, möglicherweise für optionales Verhalten oder Leistungsmerkmale

Ich schätze, dass Sie in 99 % der Fälle mit der Liste auskommen, was vorzuziehen ist.

  • zum Beispiel removeAll , oder add(null)

1voto

Acuna Punkte 1517

List Schnittstelle haben mehrere verschiedene Klassen - ArrayList y LinkedList . LinkedList wird verwendet, um eine indizierte Sammlung zu erstellen und ArrayList - um sortierte Listen zu erstellen. Sie können also in Ihren Argumenten jede beliebige davon verwenden, aber Sie können anderen Entwicklern, die Ihren Code, Ihre Bibliothek usw. verwenden, erlauben, verschiedene Arten von Listen zu verwenden, nicht nur die, die Sie selbst verwenden, also in dieser Methode

ArrayList<Object> myMethod (ArrayList<Object> input) {
   // body
}

können Sie es nur verwenden mit ArrayList , nicht LinkedList aber Sie können die Verwendung einer der List Klassen an anderen Stellen, an denen die Methode verwendet wird, ist es nur Ihre Wahl, so dass die Verwendung einer Schnittstelle kann es ermöglichen:

List<Object> myMethod (List<Object> input) {
   // body
}

In dieser Methode können Sie jedes der folgenden Argumente verwenden List Klassen, die Sie verwenden möchten:

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

list.add ("string");

myMethod (list);

SCHLUSSFOLGERUNG:

Verwenden Sie die Schnittstellen überall, wo es möglich ist, und schränken Sie sich oder andere nicht ein, andere Methoden zu verwenden, die sie verwenden möchten.

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