Яка різниця між <?> Та <? розширює Object> в Java Generics?


95

Раніше я бачив узагальнюючий знак, який означав будь-який об’єкт, але нещодавно бачив використання:

<? extends Object>

Оскільки всі об'єкти розширюють Object, чи є ці два звички синонімами?


2
Це те саме. Дивіться stackoverflow.com/questions/2274720/…
Дан,

3
@Dan Якщо ви шукаєте "? Extends Object" у цьому питанні, ви нічого не знайдете. Я читаю відповіді, щоб побачити, чи можу я щось зробити, але я не думаю, що це все. Зокрема, мова не йде про генерики.
orbfish

@Dan - Це вже інше питання. Я вже бачив це запитання і пам’ятаю принаймні згадку про тонку різницю. Дозвольте подивитися, чи зможу я його знайти ...
Пол Беллора,

Також це не один , якщо ви знайшли його: stackoverflow.com/questions/678822 / ...
orbfish

1
Тут ми йдемо: можливий копія необмежених символів узагальнення на Java (із не менш неправильною відповіддю Кевіна Бурріллона)
Пол Беллора,

Відповіді:


104

<?>і <? extends Object>є синонімами, як і слід було очікувати.

Є кілька випадків із дженериками, де extends Objectнасправді не є зайвими. Наприклад, <T extends Object & Foo>призведе до того , Tщоб стати Objectпід стиранням, в той час як з <T extends Foo>він стане Fooпід стиранням. (Це може мати значення, якщо ви намагаєтеся зберегти сумісність із попередньо використовуваним API, що використовувався Object.)

Джерело: http://download.oracle.com/javase/tutorial/extra/generics/convert.html ; це пояснює, чому java.util.Collectionsклас JDK має метод із таким підписом:

public static <T extends Object & Comparable<? super T>> T max(
    Collection<? extends T> coll
)

4
Мені незрозуміло, як стосується приклад? (оскільки він не використовує ані <?>, ані <? extends Object>)
orbfish

27
@orbfish: Це пов’язано лише з тим, що я думав, що вам це буде цікаво, оскільки це приклад, де extends Objectнасправді має значення. Якщо я помилився, то перепрошую. Сподіваємось, це буде цікавим принаймні іншим людям, які стикаються з вашим запитанням.
ruahh

@ruakh - Вас цікавили обмежені символи підстановки, а не параметри типу, але, принаймні, ви відповіли.
orbfish

1
Тоді ви мали б це сказати у своєму початковому дописі. Таким чином, його відповідь могла бути для вас більш релевантною.
liltitus27,

19

Хоча <?>це має бути ярликом <? extend object>, між ними є незначна різниця. <?>можна перепрофілювати, тоді <? extend object>як ні. Причина, по якій вони це зробили, полягає в тому, щоб полегшити розрізнення типу, що підлягає закріпленню. Все , що виглядає як <? extends something>, <T>, <Integer>є nonreifiable.

Наприклад, цей код буде працювати

List aList = new ArrayList<>();
boolean instanceTest = aList instanceof List<?>;

але це дає помилку

List aList = new ArrayList<>();
boolean instancetest = aList instanceof List<? extends Object>;

для отримання додаткової інформації читайте дженерики Java та колекції Моріса Нафталіна


Як List <?> Може бути перепрофільований, якщо компілятор перекладе його в List <Object>, щоб отримати інформацію про те, що це за тип? загублено?
Trismegistos

Те, що я вважаю <?>, Більше розроблене для зворотної сумісності зі застарілими API. розрізнити за допомогою <Object> та <? розширює Object>, які є поштовим кодом Java 5.
Dennis C

9

<?>це скорочення для <? extends Object>. Ви можете прочитати нижче спільне посилання для отримання додаткової інформації.


<?>

"?"позначає будь-який невідомий тип, він може представляти будь-який тип в коді для. Використовуйте цей узагальнюючий знак, якщо не впевнені щодо типу.

ArrayList<?> unknownList = new ArrayList<Number>(); //can accept of type Number
unknownList = new ArrayList<Float>(); //Float is of type Number

Примітка: <?> означає будь-що. Отже, він може приймати тип, який не успадковується від Objectкласу.

<? extends Object>

<? extends Object>означає, що ви можете передати об'єкт або підклас, що розширює Objectклас.

ArrayList<? extends Number> numberList = new ArrayList<Number>(); //Number of subclass
numberList = new ArrayList<Integer>(); //Integer extends Number
numberList = new ArrayList<Float>(); // Float extends Number 

введіть тут опис зображення

T - використовується для позначення типу
E - використовується для позначення елемента
K - клавіші
V - значення
N - для чисел
Ref:

введіть тут опис зображення


"Отже, він може приймати тип, який не успадковується від класу" Об'єкт "", але всі класи Java успадковуються або неявно успадковуються від Objectкласу.
хакдзюцу
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.