Ich habe Probleme beim Navigieren in der Java-Regel zum Ableiten generischer Typparameter. Betrachten Sie die folgende Klasse mit einem optionalen Listenparameter:
import java.util.Collections;
import java.util.List;
public class Person {
private String name;
private List<String> nicknames;
public Person(String name) {
this(name,Collections.emptyList());
}
public Person(String name,List<String> nicknames) {
this.name = name;
this.nicknames = nicknames;
}
}
Mein Java-Compiler gibt den folgenden Fehler aus:
Person.java:9: The constructor Person(String, List<Object>) is undefined
Aber Collections.emptyList()
kehren geben <T> List<T>
, nicht List<Object>
. Das Hinzufügen einer Besetzung hilft nicht
public Person(String name) {
this(name,(List<String>)Collections.emptyList());
}
ergibt
Person.java:9: inconvertible types
Verwenden EMPTY_LIST
stattemptyList()
public Person(String name) {
this(name,Collections.EMPTY_LIST);
}
ergibt
Person.java:9: warning: [unchecked] unchecked conversion
Durch die folgende Änderung wird der Fehler behoben:
public Person(String name) {
this.name = name;
this.nicknames = Collections.emptyList();
}
Kann jemand erklären, gegen welche Regel zur Typprüfung ich hier stoße und wie ich sie am besten umgehen kann? In diesem Beispiel ist das endgültige Codebeispiel zufriedenstellend, aber bei größeren Klassen möchte ich in der Lage sein, Methoden zu schreiben, die diesem Muster "optionaler Parameter" folgen, ohne Code zu duplizieren.
Für zusätzliche Gutschrift: Wann ist es angebracht, EMPTY_LIST
im Gegensatz zu zu verwenden emptyList()
?
quelle
Antworten:
Das Problem , das Sie sind Begegnungs ist , dass auch wenn die Methode
emptyList()
zurückkehrtList<T>
, haben Sie nicht mit der Art vorausgesetzt , es ist , so wird standardmäßig auf die RückkehrList<Object>
. Sie können den Typparameter angeben und Ihren Code wie erwartet verhalten lassen:Wenn Sie jetzt eine direkte Zuweisung vornehmen, kann der Compiler die generischen Typparameter für Sie ermitteln. Es heißt Typinferenz. Wenn Sie dies beispielsweise getan haben:
dann würde der
emptyList()
Anruf korrekt a zurückgebenList<String>
.quelle
this
muss die erste Anweisung im Konstruktor sein.Sie möchten verwenden:
Wenn Sie sich die Quelle für die leere Liste ansehen, sehen Sie, dass sie tatsächlich nur a ausführt
quelle
Die Methode emptyList hat folgende Signatur:
Das
<T>
bedeutet, dass vor dem Wort Liste der Wert des generischen Parameters T aus dem Variablentyp abgeleitet wird, dem das Ergebnis zugewiesen ist. Also in diesem Fall:Der Rückgabewert wird dann explizit von einer Variablen vom Typ referenziert
List<String>
, damit der Compiler ihn herausfinden kann. In diesem Fall:Es gibt keine explizite Rückgabevariable, mit der der Compiler den generischen Typ ermitteln kann. Der Standardwert ist daher
Object
.quelle