Kolekcje.emptyList () zwraca listę?
Mam problem z nawigacją w regułach Javy do wnioskowania ogólnych parametrów typu. Rozważmy następującą klasę, która ma opcjonalny parametr listy:
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;
}
}
Mój kompilator Javy podaje następujący błąd:
Person.java:9: The constructor Person(String, List<Object>) is undefined
Ale Collections.emptyList()
zwraca typ <T> List<T>
, a nie List<Object>
. Dodawanie obsady nie pomaga
public Person(String name) {
this(name,(List<String>)Collections.emptyList());
}
Person.java:9: inconvertible types
Użycie EMPTY_LIST
zamiast emptyList()
public Person(String name) {
this(name,Collections.EMPTY_LIST);
}
Person.java:9: warning: [unchecked] unchecked conversion
Podczas gdy następująca zmiana powoduje, że błąd daleko:
public Person(String name) {
this.name = name;
this.nicknames = Collections.emptyList();
}
Czy ktoś może wyjaśnić, z jaką regułą sprawdzania typu mam tu do czynienia i jak najlepiej to obejść? W tym przykładzie końcowy przykład kodu jest zadowalający, ale przy większych klasach chciałbym móc pisać metody zgodnie z tym" opcjonalnym parametrem " bez powielania kodu.
Dla dodatkowego kredytu: Kiedy należy używać EMPTY_LIST
W przeciwieństwie do emptyList()
?
3 answers
Napotkany problem polega na tym, że mimo że metoda emptyList()
zwraca List<T>
, nie podałeś jej typu, więc domyślnie zwraca List<Object>
. Możesz podać parametr type i sprawić, aby Twój kod zachowywał się zgodnie z oczekiwaniami, w następujący sposób:
public Person(String name) {
this(name,Collections.<String>emptyList());
}
Teraz, gdy robisz proste przypisanie, kompilator może obliczyć ogólne parametry typu dla Ciebie. To się nazywa wnioskowanie typu. Na przykład, jeśli to zrobiłeś:
public Person(String name) {
List<String> emptyList = Collections.emptyList();
this(name, emptyList);
}
Wtedy wywołanie emptyList()
zwróci poprawnie List<String>
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-20 20:34:46
Chcesz użyć:
Collections.<String>emptyList();
Jeśli spojrzysz na źródło tego, co robi emptyList, zobaczysz, że faktycznie robi
return (List<T>)EMPTY_LIST;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-20 20:34:38
Metoda emptyList ma taki podpis:
public static final <T> List<T> emptyList()
To <T>
przed listą słów oznacza, że wyprowadza wartość parametru ogólnego T z typu zmiennej, do której jest przypisany wynik. Więc w tym przypadku:
List<String> stringList = Collections.emptyList();
Zwracana wartość jest następnie jawnie odwoływana przez zmienną typu List<String>
, więc kompilator może to rozgryźć. W tym przypadku:
setList(Collections.emptyList());
Nie ma jawnej zmiennej zwrotnej, której kompilator mógłby użyć do określenia typu generycznego, więc domyślnie jest to Object
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-20 20:25:29