Während ich an einem Projekt mit den neuen Streams von Java 8 arbeitete, bemerkte ich, dass wenn ich Stream#toArray()
in einem Stream anrief, es ein Object[]
anstelle von T[]
zurückgab. Überrascht wie ich war, fing ich an, den Quellcode von Java 8 zu untersuchen und konnte keinen Grund finden, warum sie Object[] toArray();
nicht als T[] toArray();
implementiert haben. Gibt es Gründe dafür, oder ist es nur eine (un) Konsistenz?
EDIT 1: Ich habe in den Antworten bemerkt, dass viele Leute sagten, dies wäre nicht möglich, aber dieser Code-Ausschnitt kompiliert und liefert das erwartete Ergebnis?
%Vor% Dies ist das gleiche Problem, das List#toArray()
hat. Type Erase verhindert, dass wir den Array-Typ kennen, den wir zurückgeben sollten. Berücksichtigen Sie Folgendes:
Ein Object[]
ist nicht ein String[]
und kann daher unabhängig von der Besetzung keinem zugewiesen werden. Dieselbe Idee gilt für Stream
und List
. Verwenden Sie die überladene Methode toArray(..)
.
Versuchen Sie:
%Vor%Die no-arg toArray () -Methode gibt nur ein Object [] zurück, aber wenn Sie eine Array-Factory übergeben (die einfach als Array-Konstruktorreferenz dargestellt werden kann), können Sie den gewünschten (kompatiblen) Typ erhalten.
Über den Grund, warum toArray()
Object[]
zurückgibt: Dies liegt an der Art des Löschens. Generische Typen verlieren ihre Typparameter zur Laufzeit, so dass Stream<Integer>
, Stream<String>
und Stream
dieselben Typen werden. Daher gibt es keine Möglichkeit, den Komponententyp des zu erstellenden Arrays zu bestimmen. Eigentlich könnte man die Arten von Array-Elementen mit Reflektion analysieren und dann versuchen, ihre mindestens obere Grenze , aber das ist zu kompliziert und langsam.
Es gibt eine Möglichkeit, R[]
array durch Verwendung von überladenem toArray(IntFunction<A[]> generator)
Methode. Diese Methode gibt dem Aufrufer die Möglichkeit, den Typ des Arrays zu wählen. Sehen Sie sich diese SO-Frage für Codebeispiele an: Wie konvertiert man einen Java 8-Stream in ein Array? .