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.

Author: Jeff Axelrod, 2010-01-06

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
 18
Author: Tom Hawtin - tackline,
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:

  1. 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"

  2. Z punktu widzenia reifiablity są one inne. JLS 4.6 i 4.7 kodyfikują List<?> jako typ reifiable, ale List<? 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 .

 32
Author: notnoop,
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);}
}
 4
Author: Chris Jester-Young,
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.

[[11]}jednak przeszukując spec, nie ma żadnych dowodów na to, że wildcard musi mają górną granicę (lub dolną). "Nieograniczony "? 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.
 2
Author: irreputable,
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.

 -1
Author: Malfist,
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ę.

 -1
Author: Kevin Bourrillion,
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