2016-04-01 21 views
6

Dies ist der Code von meinem Lehrbuch:Java Generics Typ Casting notwendig?

Stack<String>[] a = (Stack<String>[]) new Stack[N]; 

Meine Fragen sind:

  1. Warum ist es "neue Stack [N]"?
  2. Warum müssen Sie die Typkonvertierung für das neue erstellte Stack-Array durchführen? Ich versuchte es mit nur

    Stack<String>[] a = new Stack[N]; 
    

und es kompiliert und lief gut. Auch nach dem Drücken von Strings in ein und Drucken der Pop-Methode. Auch würde ein int in drängen sofort geben Sie mir einen Compiler-Fehler so, warum ist es notwendig, warf es zu

Stack<String>[] 

speziell auf Typ?

+2

Verwenden Sie Java 8? Einige Dinge sind mit seinem Generikasystem besser geworden. – Makoto

Antwort

4

Sie können keine Arrays mit parametriertem Typ erstellen (siehe Restrictions on Generics). Sie können also ... = new Stack<String>[N] nicht verwenden. Die Verwendung von ... = new Stack[N] funktioniert, aber Sie werden eine Warnung für die ungeprüfte Konvertierung haben (verwenden Sie -Xlint in javac, um die Warnung zu sehen).

So ist die einzige richtige Möglichkeit, das Array mit einem Rohparameter zu erstellen und dann eine geprüfte Besetzung auf den gewünschten Typ anzuwenden.

+0

Ich sehe! Danke vielmals. Ich lese den Link durch, aber vielleicht ist es Wiederholung, aber es macht jetzt mehr Sinn. – Myang310

+0

Also, was ist der Schaden, wenn man eine geprüfte Besetzung NICHT mit einbezieht? – Myang310

+1

Nicht wirklich schaden. Die ungeprüfte Konvertierung besteht aus Kompatibilitätsgründen mit einer älteren Java-Vorgenerika-Version. Warnungen erinnern dev, dass sie Generizität verwenden sollten. Siehe [Ungeprüfte Konvertierung] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.9). – zer0chain

1
  1. nicht sicher, was Sie von dieser Frage bedeuten, aber wenn Sie meinen, warum nicht neue Stack<String>[N] es ist, weil Java arrays does not support parameterized array creation.

  2. Wegen meiner Antwort in (1) die erstellte Array nicht parametriert , aber Sie ordnen es einer parametrisierten Variablen zu. Und dafür die optionale, aber bevorzugt checked cast.

+0

Ahh ich verstehe. Das ist die Terminologie dafür (nicht parametrisiert). Was ist also die Gefahr, wenn Sie ihm keine parametrisierte Variable zuweisen und sie als Stack [N] beibehalten? – Myang310

+0

Wie @ zer0chain erwähnt, keine Gefahr wirklich, nur eine Warnung, siehe [Ungeprüfte Konvertierung] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1. 9) – gustf

0

Zuerst wird, wie Sie bemerkt haben, ist die Besetzung nicht notwendig. Ohne die Besetzung erhältst du eine ungeprüfte Conversion-Warnung (während du bei der Besetzung eine ungeprüfte Cast-Warnung erhältst). Die Konvertierung zwischen einem Rohtyp und einem parametrisierten Typ kann ohne explizite Umwandlung erfolgen (Sie erhalten nur eine Warnung).

Wenn Sie fragen, warum es nicht möglich ist, ein Array eines parametrisierten Typs direkt zu erstellen, liegt das daran, dass Arrays in Java garantieren, dass sie zur Laufzeit niemals ein Element enthalten, das keine Instanz des Komponententyp, mit dem das Array erstellt wurde. d.h., jedes Mal, wenn etwas in das Array gegeben wird, wird eine Laufzeitprüfung durchgeführt, um zu überprüfen, ob es sich um eine Instanz des Komponententyps des Arrays handelt.

Wie Sie vielleicht wissen, generische Typargumente gibt es nicht bei der Kompilierung, und es ist nicht möglich instanceof einen parametrisierte Typen zur Laufzeit zu überprüfen. Es ist nur möglich, die bestätigten Typen instanceof zu überprüfen. Wenn ein Array mit einem parametrisierten Typ erstellt werden könnte, wäre es nicht in der Lage, seinen Kontrakt zu erfüllen, um zu überprüfen, ob alles, was zur Laufzeit eingegeben wird, eine Instanz dieses Typs ist. Jemand, der sich auf diese Garantie von Arrays verlässt, wird unerwartete Ergebnisse erhalten. Daher wird es Ihnen nicht erlauben, es zu tun. Das Erstellen eines Arrays mit einem Rohtyp (was Sie getan haben) oder mit einem Platzhalter-parametrisierten Typ ist jedoch in Ordnung, da es sich um verdinglichte Typen handelt. Obwohl Sie es als Array eines parametrisierten Typs verwenden, haben Sie dies durch eine ungeprüfte Konvertierung (mit einer Warnung) getan, so dass Sie die Verantwortung für eventuell auftretende Sicherheitsprobleme übernehmen.