Generische Array-Erstellung

8

Hier ist der Code, den ich verwende

%Vor%

Ich habe Leute gesehen, die sagen, dass das Erstellen eines Arrays wie diesem eine schlechte Idee ist, da es nicht typsicher ist. Aber jedes Mal, wenn ich es benutze, habe ich keine Probleme damit. Wann würde ein solches Array ein Problem verursachen?

Danke

    
Stripies 05.04.2012, 15:45
quelle

7 Antworten

4

Hier ist ein Beispiel, das Probleme verursacht:

%Vor%

Ihr Code funktioniert, denn wenn Sie Ihren generischen Parameter <T> deklarieren, ist er ungebunden, dh er erweitert Object . Wenn Sie Ihr Array in (T[]) umwandeln, werden Sie tatsächlich nach (Object[]) umgeworfen, da dies der beste ist, den der Compiler ausführen kann. Wenn Sie Ihr Array in Ihrem Code behalten, sollten Sie nicht zu viele Probleme haben. Aber wenn jemand außerhalb Ihres Codes dieses Array abrufen kann und Ihre Klasse mit einem anderen Typ als Objekt instanziiert hat, hat er eine ClassCastException.

    
Guillaume Polet 05.04.2012, 16:12
quelle
4

Sie können kein Array von T erstellen, weil Java zur Laufzeit nicht weiß, was der Typ von T ist. Dies liegt daran, dass in Java Generics mit Type-Löschung implementiert sind. Dies bedeutet, dass der Compiler die meisten generischen Typinformationen verwirft, nachdem sichergestellt wurde, dass alles OK ist.

Bei Arrays ist die Geschichte anders, weil Java den genauen Typ von T kennen muss, um das gegebene Array zu erstellen, und da solche Dinge nicht bestimmt werden können, können Sie kein Array eines generischen Typs erstellen.

Sie können eine Instanz des tatsächlichen Arrays angeben, das Sie verwenden möchten, und der Java-Compiler kann sicherstellen, dass er vom richtigen Typ ist:

%Vor%

Die java.utils.Arrays.copy -Methode bietet eine Alternative, die sorgfältig Generika und Reflexionen verwendet, die Sie als Referenz für das verwenden können, was Sie tun möchten.

%Vor%     
Edwin Dalorzo 05.04.2012 16:11
quelle
2

Etwas, das nicht typsicher ist, verursacht an sich keine Probleme. Aber es kann Probleme bei der Kompilierung ausblenden, die erst im richtigen Moment erscheinen.

Sie könnten ohne Probleme in einer sicheren Umgebung ohne Typ arbeiten, aber es ist eine schlechte Angewohnheit, nur weil eine typsichere Umgebung Ihnen garantiert, dass Sie keine allgemeinen Laufzeitfehler haben. Ich habe momentan keine, aber Sie haben keine Garantie, und diese sind wirklich wichtig. Jede Sicherheit, der Sie vertrauen können, bedeutet weniger Aufwand.

    
Jack 05.04.2012 15:55
quelle
1

Die anderen Leute liegen falsch. Es gibt keine andere Möglichkeit, das Array zu erstellen, es sei denn, Sie haben zum Zeitpunkt der Erstellung eine Instanz des Typs. Siehe auch Wie erstellt man ein generisches Array in Java?

Wenn du den Typ instance hast (= etwas, das den Typ Class<T> hat), kannst du java.lang.reflect.Array.newInstance(Class<?>, int) aufrufen, aber selbst dann brauchst du den Cast, also warum?

Ich würde sagen, die Dinge wären anders, wenn der Typ von elements Object statt T wäre, aber da dies nicht der Fall ist, ist der Code vollkommen in Ordnung.

Wenn Sie das weiter ausblenden möchten, können Sie eine Hilfsmethode schreiben:

%Vor%

Dadurch wird ein Array erstellt, ohne dass beim Aufruf ein Cast erforderlich ist.

    
Aaron Digulla 05.04.2012 15:56
quelle
1

Es ist sicherer, in diesen Fällen Collection zu verwenden. Mach einfach etwas wie

%Vor%

Wie auch immer, von dem, was ich kenne, wird das Erstellen eines generischen Arrays nicht wirklich Probleme verursachen, aber "riecht schlecht", da es explizites Typcasting erfordert. Brauchen Sie in diesem Fall wirklich ein Array?

    
Caesar Ralf 05.04.2012 16:00
quelle
1
  

Ich habe Leute gesehen, die sagen, dass das Erstellen eines solchen Arrays schlecht ist   Idee, weil es nicht typsicher ist. Aber jedes Mal, wenn ich es benutze,   Habe keine Probleme damit. Wann würde ein Array wie dieses verursachen   ein Problem?

Die Leute sagen, es sei eine schlechte Idee, weil es logisch falsch ist, ein Objekt mit dem Laufzeittyp Object[] auf T[] zu setzen, wenn T nicht Object ist.

Sie sehen jedoch keine unmittelbaren Probleme, da innerhalb der Klasse (im Rahmen von T ) T gelöscht wird. Daher ist die Umwandlung von Object[] nach T[] nicht aktiviert.

Wenn Sie diese Variable nur innerhalb Ihrer Klasse (innerhalb des Bereichs der Typvariablen T ) verwenden, geben Sie sie niemals an Personen außerhalb der Klasse zurück, und Menschen außerhalb der Klasse können auf keinen Fall zurück Zugriff darauf erhalten, dann wird es keine Probleme verursachen.

Tatsächlich gibt es Vorteile für die Art und Weise, wie Sie es tun - Sie erhalten alle Vorteile der generischen Typprüfung beim Abrufen und Setzen von Elementen des Arrays, die Sie nicht erhalten würden, wenn Sie einfach dem vollständigen "type" folgen würden -safe "Lösung der Verwendung einer Variablen vom Typ Object[] , in diesem Fall müssten Sie manuell Dinge werfen, die Sie daraus erhalten.

Sie werden ein Problem bekommen, wenn Sie diese Array-Variable nach außen zurückgeben (oder anderweitig der Außenseite erlauben, darauf zuzugreifen) als Typ T[] , weil der aufrufende Code einen bestimmten Array-Typ erwartet und die Generics dies tun fügen Sie eine Umwandlung in den aufrufenden Code ein, wenn sie dieses Array empfängt, und die Umwandlung wird zur Laufzeit fehlschlagen (da zB Object[] keine String[] ist; sie sind zur Laufzeit unterschiedliche Typen). Hier ist ein einfaches Beispiel:

%Vor%     
newacct 06.04.2012 00:37
quelle
0

Möglicherweise haben Sie Probleme mit Vergleichen und Drucken. Grundsätzlich ist es immer wichtig, dass der Typ für die Formatierung wichtig ist. Wie Sie es haben das System hat keine Ahnung, welche Daten im Array sind

    
RyanS 05.04.2012 15:48
quelle

Tags und Links