2010-11-30 6 views
11

Mögliche Duplizieren:
Why does Guava's ImmutableList have so many overloaded of() methods?Warum liefern Guava-Klassen so viele Fabrik-Methoden, anstatt nur eine, die Varargs braucht?

bei Guava sucht ImmutableList (und einigen anderen Klassen), werden Sie viele überladene of Bequemlichkeit Methoden ("Gibt eine unveränderliche Liste mit den finden gegeben Elemente, in der Reihenfolge. "), die eine andere Anzahl von Parametern annehmen:

... 
public static <E> ImmutableList<E> of(E e1, E e2, E e3) 
public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4) 
public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5) 
... 

Den ganzen Weg zu dieser:

public static <E> ImmutableList<E> of(E e1, 
             E e2, 
             E e3, 
             E e4, 
             E e5, 
             E e6, 
             E e7, 
             E e8, 
             E e9, 
             E e10, 
             E e11, 
             E e12, 
             E... others) 

Einige Kollegen von mir diesen dummen betrachten, fragen, warum es ist nicht nur eine Methode: of(E... elements). Sie vermuten, dass es eine schlecht geführte Performance- "Optimierung" ist, die in die Kategorie "Denkst du, du bist schlauer als Compiler" oder so ähnlich fällt.

Meine Ahnung ist, dass Kevin Bourrillion et al. Setze diese Methoden aus einem echten Grund ein. Kann jemand erklären (oder spekulieren), was dieser Grund sein könnte?

+0

Wenn die Bibliothek älter wäre, würde ich vermuten, dass die Methoden vor Java 5.0 geschrieben wurden. Der ursprüngliche Code könnte so alt sein und wurde nicht umgestaltet. –

+0

@Peter: Es macht nichts, dass es die Rückwärtskompatibilität brechen würde, um sie zu entfernen (der Code wäre gegen eine Methode verknüpft, die nicht mehr existiert), die sie nicht wollen. Obwohl sie zumindest veraltet sein konnten, war das so. –

+0

@Mark, ironischerweise ist es der von (E []) Builder, der veraltet ist. ;) –

Antwort

10

Der Kommentar in der source sagt:

// These go up to eleven. After that, you just get the varargs form, and 
// whatever warnings might come along with it. :(

Also, das da getan wurde varargs Methoden eine Warnung mit generischen Argumenten erzeugen.

0

Es ist der Aufwand für die Erstellung eines Varargs-Array für die häufigsten Anwendungsfälle zu vermeiden. Dies ist nach dem Vorbild EnumSet.of(..) gestaltet.

+3

kann ich nicht so sein, weil diese Methoden die gleiche Vararg-Methode intern aufrufen. – axtavt

+0

Es gibt ein Kapitel darüber in Effective Java, aber ich kann es nicht im Internet finden. –

3

Ich denke, es ist zu vermeiden unchecked generic array creation Warnung, wenn E ein generischer Typ ist.

+1

Ich bin mir nicht sicher, ob das der Grund war, aber es ist sicherlich eine relevante Überlegung. Es ist dumm, aber derzeit in Java erhalten Sie diese Warnung, wenn Sie eine varargs-Methode mit einem generischen Typ aufrufen, was lächerlich ist, da Sie als Aufrufer niemals mit dem Array interagieren können, indem Sie die Methode über varargs aufrufen. Ich glaube, entweder Java 7 oder 8 wird eine Änderung einführen, um die Warnung stattdessen in die Methodendeklaration zu verschieben. –

-1

Wirklich der Compiler ist wirklich dumm, die JVM hat die meisten Smart, aber es ist immer noch nicht schlau genug, um die Notwendigkeit zu beseitigen, ein Array für einen Vararg zu erstellen.

Ob sich das Speichern des Arrays wirklich lohnt, ist vielleicht etwas, worüber der Autor sich keine Sorgen machen sollte. vielleicht weiß er, dass es keinen großen Unterschied macht, aber nicht alle Benutzer wissen, dass es sich in 99% der Fälle nicht lohnt, sich darüber Gedanken zu machen.

Wenn es Google-Sammlungen waren, war dieser Teil der Beschreibung „High-Performance unveränderlicher Implementierungen der Standardsammlungstypen, zum Beispiel ImmutableSet“

+2

Vararg Parameter _are_ Arrays, es ist also natürlich nicht möglich, ein Array für ein Varargs-Argument zu erstellen. Anyway, 'ImmutableList' konstruiert das Array varargs intern für alle diese Überladungen (mit Ausnahme der Liste der einzelnen Elemente). – ColinD

-1

Was kann ich mich vorstellen ist Verwirrung durch den Compiler zu vermeiden.

Wenn wir nur hatten,

public static ImmutableList<E> of(E element); //Option 1 

und

public static ImmutableList<E> of(E... elements); //Option 2 

und in Ihrem Code hatten wir

ImmutableList<String> list = ImmutableList.of("Value"); 

Der Compiler würde nicht wissen, ob 1-Option aufzurufen oder Option 2.

Die Das muss ein berechtigter Grund sein, warum Josh Bloch, Kevin Bourrillion und sein Team "lächerlich" auf die Methode of(...) dachten.

+0

Der Compiler wird die spezifischste Methode verwenden, die dem Aufruf entspricht ... in diesem Fall, Option 1. – ColinD

+0

Außerdem, wenn das alles wäre, würde es nur eine Überladung wie von (E, E, E .. .) '. – ColinD

Verwandte Themen