2010-11-26 4 views
2

Wenn ich ein (generic) nennen varargs Verfahren mit Objekten verschiedener Klassen, erhalte ich eine interessante Warnung:Warnung: Eine generische Array von Objekt & Serializable & Vergleichbare <?> für einen varargs Parameter erstellt

List<?> result = Arrays.asList("1", 1); 

Ein generisches Array Objekt & Serializable & vergleichbar ist für einen varargs Parameter erstellt

ich durch Gießen der Warnung los auf eine gemeinsame Schnittstelle oder Klasse bekommen,

List<Serializable> result = asList((Serializable) "1", (Serializable) 1); 

aber was bedeutet Object&Serializable&Comparable<?>? Kann es auch in generischen Typanmerkungen für Methodensignaturen verwendet werden (wie extends oder super)?

Antwort

3

Die Klasse Object und die Schnittstellen Comparable und Serializable sind die Supertypen, die die Klassen Integer und String gemeinsam haben.

Aufgrund der Typauslöschung in Generics und der Kovarianz von Arrays mischen sich Generika und Arrays nicht sehr gut miteinander. Die Methode Arrays#asList nimmt eine Varargs als Eingabe, und in Java sind Varargs intern mit Arrays implementiert. Daher die Warnung. (Sie können mehr darüber in Josh Bloch Effektiv Java lesen.)

Nun zu Ihrer zweiten Frage,.kann in Methodensignaturen verwendet werden, um die Einschränkungen für Typparameter anzugeben. (Siehe this answer.) Java erlaubt solche Typen jedoch nicht in generischen Typanmerkungen.

Mit anderen Worten, gilt folgendes:

public static void <A extends Comparable<A> & Serializable> meth(A a); 

aber die folgenden nicht:

List<Serializable & SomeOtherInterface> list = ...; 
+0

EXTRA INFO: Scala ermöglicht solche Typ Anmerkungen. http://ideone.com/gCTEd – missingfaktor

1

Ich denke, da alle Objekttypen serialisierbar und vergleichbar sind (String und Integer) dann Compiler sagen, dass alle Elemente im Array Objekttyp UND implementiert Serializable und vergleichbare Schnittstellen haben.

Ich bezweifle, dass Serializable & Vergleichbare normalerweise in Java-Code verwendet werden können, können Sie immer sie normalerweise implementieren können und erhalten die gleiche Warnung :-)

public class ComparableAndSerializableClass implements Comparable<ComparableAndSerializableClass>, Serializable{ 

    public static void main(String[] args) { 
     List<?> result = Arrays.asList("1", 1, new ComparableAndSerializableClass()); 
     for (Object comp : result) { 
      System.out.println(comp.getClass()); 
     } 
    } 

    @Override 
    public int compareTo(ComparableAndSerializableClass o) { 
     return 0; 
    } 
} 
0

Wenn Sie einen generischen Typ wie Foo<...> haben, dann können Sie eine Hilfsmethode verwenden, um Anruf Arrays.asList() für Sie:

public static List<Foo<?>> asList(Foo<?> ... foos) { 
    return Arrays.asList(foos); 
} 

Der Java-Compiler wird erstellen ein generisches Array für den Parameter varargs, das Sie dann sicher im Aufruf von Arrays.asList() verwenden können. Wenn Sie möchten, dass alle Foo denselben Innentyp haben:

public static <T> List<Foo<T>> asList(Foo<T> ... foos) { 
    return Arrays.asList(foos); 
} 
Verwandte Themen