Unbounded wildcards in Java
Czy istnieje kiedykolwiek różnica między niepohamowaną wildcard np <?>
i bounded wildcard, którego bound jest Object
, np <? extends Object>
?
Przypominam sobie, że gdzieś czytałem, że była różnica we wczesnych projektach leków generycznych, ale nie mogę znaleźć tego źródła.
6 answers
Jako punkt pedntry, Istnieje różnica, czy klasa / interfejs / konstruktor / metoda deklaruje bound (inny niż extends Object
).
interface Donkey<T extends Thing> { }
...
Donkey<? extends Object> foo; // FAIL
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
2010-01-07 01:03:54
Z praktycznego punktu widzenia dla większości ludzi, <? extends Object>
jest tym samym, co <?>
, Jak wszyscy tu sugerowali.
Różnią się jednak dwoma bardzo drobnymi i subtelnymi punktami:
JVMS (Java Virtual Machine Specification) ma specjalną specyfikację dla niepohamowanych symboli wieloznacznych, ponieważ
ClassFileFormat-Java5
Określa, że niepohamowane symbole wieloznaczne są kodowane jako*
, podczas gdy symbole wieloznaczne są kodowane jako+Ljava/lang/Object;
. Taka zmiana wyciekłaby przez każdą bibliotekę, która analizuje kod bajtowy. Pisarze kompilatorów musieliby również poradzić sobie z tym problemem. Z do "formatu pliku klasy"Z punktu widzenia reifiablity są one inne. JLS 4.6 i 4.7 kodyfikują
List<?>
jako typ reifiable, aleList<? extends Object>
jako typ kasowany. Każdy Edytor bibliotek dodający.isReifiable()
(np. mjc lib) musi to uwzględnić, aby stosować się do terminologii JLS. Z JLS 4.6 i 4.7 .
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
2016-03-22 00:31:56
Z eksperymentów wynika, że na przykład, List<?>
i List<? extends Object>
są kompatybilne z przypisaniami w obie strony, a metoda, która ma podpis przy użyciu jednego z nich, może zostać nadpisana podpisem przy użyciu drugiego. np.,
import java.util.List;
class WildcardTest<T> {
public void foo(List<? extends T> bar) {}
}
class WildcardTest2 extends WildcardTest<Object> {
@Override
public void foo(List<?> bar) {super.foo(bar);}
}
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
2010-01-06 20:44:11
To skomplikowane...
Dla dowolnej zmiennej typu T
spec mówi http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4
Każda zmienna typu ... ma Wiązanie. Jeśli dla zmiennej typu nie jest zadeklarowana Żadna bound, zakładany jest obiekt.
Można by pomyśleć, że to prawda również dla wildcard i ?
powinno być tylko skrótem ? extends Object
.
?
jest traktowany konsekwentnie wyraźnie od ograniczonych symboli wieloznacznych.
Możemy wywnioskować z podtypów, że List<?>
i List<? extends Object>
są podtypami siebie nawzajem, tzn. są W zasadzie tego samego typu.
Jednak spec traktuje je oddzielnie. Na przykład http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.7 List<?>
jest typem reifiable, ale List<? extends Object>
nie jest, który oznacza
// ok
List<?>[] xx = {};
// fail
List<? extends Object>[] yy = {};
// ok
boolean b1 = (y instanceof List<?>);
// fail
boolean b2 = (y instanceof List<? extends Object>);
Nie rozumiem dlaczego. Można powiedzieć, że symbole wieloznaczne muszą mieć górną i dolną granicę, domyślnie Object
i null type
.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
2013-01-15 22:23:03
Wszystko w Javie z wyjątkiem obiektu primitives extend, więc nie, nie byłoby różnicy. Autoboxing pozwala na użycie prymitywów, więc można powiedzieć, że wszystko w Javie jest obiektem.
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
2010-01-06 20:38:01
<? extends Object>
jest dokładnie taka sama jak <?>
. Przepraszam, że nie mam pod ręką referencji, ale ... tak. :)
EDIT: oczywiście, myślałem tylko z konkretnej perspektywy, kiedy to powiedziałem. Zignoruj moją odpowiedź (która została dość poprawnie odrzucona) i zobacz wyżej oceniane odpowiedzi na prawdziwą historię.
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
2010-01-20 21:44:08