Wie kann man dieses scheinbar inkonsistente Java-Verhalten erklären?

8

Wenn ich die Java-Methode

schreibe %Vor%

dann kann ich diese Methode über

aufrufen %Vor%

sowie

%Vor%

und beide Anrufe werden genau gleich behandelt. Die beiden Anrufe jedoch

%Vor%

und

%Vor%

werden nicht gleich behandelt. Der Abschnitt zum Bewerten von Argumenten in der JLS states "Der letzte formale Parameter von m hat notwendigerweise den Typ T[] für einige T " also warum ist der "letzte formale Parameter" im Fall (b) nicht nicht ein Integer-Array, das eine dreielementige Liste wie case (a) erstellen würde?

Das Einzige, woran ich denken kann ist, dass Arrays.asList generisch ist und etwas über Typenkompatibilität (erwähnt in JLS Abschnitt 15.12.4.2) hier spielt, aber ich kann nicht ganz Setzen Sie meinen Finger auf den eigentlichen Satz in der JLS, der die beiden Fälle unterscheidet.

Der Kommentar in der JLS spricht über die Notwendigkeit, diese Semantik sorgfältig zu erstellen, um das Zusammenspiel zwischen "parametrisierten Typen und Array-Typen, die in einer Java Virtual Machine mit ausgelöschten Generics vorkommen", zu verarbeiten. co_de% und f scheinen sich inkonsistent zu verhalten. Im ersten Fall kann ich meine Argumente "auspacken" oder "packen" und alles ist gleich; im letzteren Fall sind die beiden Fälle unterschiedlich.

Wie wird das in sprachsprachlichen Begriffen erklärt?

    
Ray Toal 26.11.2014, 06:28
quelle

2 Antworten

5

Arrays.asList ist als Parameter T... definiert, und der Text sieht es als ein Argument vom Typ T[] . % Co_de% muss jedoch ein Referenztyp sein (wie jeder Typparameter), und T ist kein Referenztyp. Aus diesem Grund gibt es keine Möglichkeit, int mit einem Array für Varargs-Zwecke kompatibel zu machen. (Und das Ergebnis wäre new int[]{...} , was nicht erlaubt ist.) Die einzige Alternative ist, es als ein einzelnes Objekt zu behandeln, und daher wird List<int> hier T sein, was ein Referenztyp ist, und die Funktion wird gib ein int[] zurück.

Ich denke, das ist der Grund, obwohl ich immer noch die genaue Sprache nachschlagen müsste. Es beinhaltet wahrscheinlich die Typinferenzregeln, die ich nicht beherrscht habe.

Allerdings habe ich Folgendes versucht:

%Vor%

(Beachten Sie, dass ich absichtlich einen List<int[]> raw-Typ verwendet habe, was ich in echtem Code nicht tun würde). Die Ausgabe:

%Vor%     
ajb 26.11.2014, 06:39
quelle
2
%Vor%

1 2 3 werden zu Integer-Objekten autoboxiert, die dann in einem Objekt []

platziert werden %Vor%

erzwingt die 3 Ganzzahlen in ein primitives int-Array.

Arrays.asList() erwartet Object[] , sodass das Array int[] in ein einzelnes Element Object[]

gestellt wird     
slipperyseal 26.11.2014 06:40
quelle