Java SafeVarargs-Annotation, existiert ein Standard oder eine Best Practice?
Habe ich vor kurzem über java @SafeVarargs annotation. Googeln für was macht eine Variable Funktion in Java unsicher ließ mich ziemlich verwirrt (heap-Vergiftung? gelöscht Arten?), also ich würde gerne ein paar Dinge wissen:
- Was macht eine Variable Java-Funktion als unsicher @SafeVarargs Sinn (vorzugsweise erklärte in form einer in-depth-Beispiel)?
- Warum ist diese Anmerkung im Ermessen des Programmierers? Ist das nicht etwas, was der compiler sollte in der Lage sein zu überprüfen?
- Gibt es einige standard einhalten muss, um sicherzustellen, seine Funktion ist in der Tat varags sicher? Wenn nicht, was sind die besten Methoden, um sicherzustellen, dass es?
Kommentar zu dem Problem
Haben Sie gesehen, das Beispiel (und Erklärung) in JavaDoc?
Für die Dritte Frage, eine Praxis ist immer ein erstes element und der andere:
retType myMethod(Arg ersten, Arg... andere)
. Wenn Sie nicht geben Sie
, wird ein leeres array ist erlaubt, und Sie können sehr gut haben eine Methode mit dem gleichen Namen mit den gleichen Rückgabetyp der Einnahme keine Argumente, was bedeutet, dass die JVM wird eine harte Zeit, herauszufinden, welche Methode aufgerufen werden soll. @jlordo ich Tat, aber ich verstehe nicht, warum Ihr in der varargs Kontext kann man leicht replecate diese situation außerhalb einer varargs-Funktion (überprüft dies, läßt sich mit dem erwarteten Typ Sicherheits-Warnungen und Fehler zur Laufzeit)..
InformationsquelleAutor der Frage Oren | 2013-01-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
1) Es gibt viele Beispiele im Internet und auf StackOverflow über das jeweilige Problem mit generics und varargs. Im Grunde ist es, wenn Sie eine variable Anzahl von Argumenten von einem Typ-parameter Typ:
In Java varargs sind syntaktischer Zucker, der erfährt eine einfache "neu-schreiben" zur compile-Zeit: ein varargs-parameter von Typ
X...
wird umgewandelt in einen parameter vom TypX[]
; und jedes mal, wenn ein Anruf aus dieser varargs-Methode, der compiler sammelt alle "variable Argumente", das geht in die varargs-parameter und erstellt ein array genau wienew X[] { ...(arguments go here)... }
.Dies funktioniert gut, wenn die varargs-Typ ist Beton wie
String...
. Wenn es eine variable vom Typ wieT...
es auch funktioniert, wennT
ist bekannt, dass ein konkreter Typ für diesen Anruf. wenn z.B. die oben genannte Methode benutzt, waren Teil einer KlasseFoo<T>
, und Sie haben eineFoo<String>
Verweis aufrufenfoo
auf, es wäre okay, weil wir wissenT
istString
an diesem Punkt im code.Aber es funktioniert nicht, wenn der "Wert" von
T
ist ein anderer Typ-parameter. In Java ist es unmöglich, ein array zu erstellen von einer Typ-parameter-Komponente Typ (new T[] { ... }
). Also Java verwendet stattdessennew Object[] { ... }
(hierObject
ist die Obere GrenzeT
; wenn es eine Obere Schranke waren etwas anderes wäre es, dass stattObject
), und gibt Ihnen dann eine compiler-Warnung.Also, was ist falsch mit dem erstellen von
new Object[]
stattnew T[]
oder was auch immer? Gut, arrays in Java wissen, dass Ihre Komponententyp zur Laufzeit. So werden die übergebenen array-Objekt wird die falsche Komponente Typ zur Laufzeit.Wohl die häufigste Verwendung von varargs, einfach zu iterieren über die Elemente, das ist kein problem (Sie kümmern sich nicht um die Laufzeit-Typ des Arrays), so ist dies sicher:
Jedoch für alles, was hängt von der runtime-Komponente Typ des übergebenen array, wird es nicht sicher sein. Hier ist ein einfaches Beispiel für etwas, das unsichere und stürzt ab:
Das problem hier ist, dass wir abhängig von der Art der
args
zuT[]
um es zurückzugeben, wieT[]
. Aber eigentlich ist der Typ des Arguments zur Laufzeit ist nicht eine Instanz vonT[]
.3) Wenn Ihr Methode ein argument vom Typ
T...
(wobei T einen beliebigen Typ-parameter), dann:T
T[]
Dinge, die abhängig von der Laufzeit-Typ des Arrays umfassen: die Rückgabe wird als Typ
T[]
auf, übergeben Sie als argument an einen parameter vom TypT[]
daran, den array-Typ mit.getClass()
, übergabe an Methoden, die abhängig von der Laufzeit-Typ des Arrays, wieList.toArray()
undArrays.copyOf()
usw.2) Die Unterscheidung, die ich oben erwähnt ist zu kompliziert, zu leicht zu unterscheiden automatisch.
InformationsquelleAutor der Antwort newacct