Неограниченные подстановочные знаки в Java

Есть ли когда-либо различие между неограниченным подстановочным знаком, например. <?> и ограниченный подстановочный знак, чей связанный Object, например. <? extends Object>?

Я вспоминаю чтение где-нибудь, что было различие в ранних проектах дженериков, но не может больше находить тот источник.

19
задан Jeff Axelrod 31 March 2012 в 18:50
поделиться

5 ответов

В качестве точки опоры для педантизма, есть разница, если класс/интерфейс/конструктор/метод декларирует границу (кроме расширяет Object).

interface Donkey<T extends Thing> { }

...
    Donkey<? extends Object> foo; // FAIL
18
ответ дан 30 November 2019 в 02:27
поделиться

Из экспериментов кажется, что, например, List и List совместимы с присваиванием в обоих случаях, и метод, имеющий подпись, использующую одну из них, может быть переопределен подписью, использующей другую,

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
ответ дан 30 November 2019 в 02:27
поделиться

С практической точки зрения для большинства людей, является тем же самым, что , как все предлагали здесь.

Однако, они отличаются двумя очень малыми и тонкими моментами:

  1. JVMS (Java Virtual Machine Specification) имеет специальную спецификацию для неограниченных подстановочных знаков, так как ClassFileFormat-Java5 указывает, что неограниченный подстановочный знак кодируется как *, в то время как Объектный подстановочный знак кодируется как +Ljava/lang/Object;. Такое изменение просочится через любую библиотеку, которая анализирует байткод. Авторам компиляторов тоже нужно будет разобраться с этой проблемой. С редакций до "The class File Format"

  2. С точки зрения повторяемости, они отличаются. JLS 4.6 и 4.7 кодифицируют List как тип с возможностью повторной модификации, но List как стертый тип. Любой библиотечный писатель, добавляющий .isReifiable() (например, mjc lib) должен учитывать это, чтобы придерживаться терминологии JLS. Из JLS 4.6 и 4.7.

32
ответ дан 30 November 2019 в 02:27
поделиться

Все в java за исключением примитивов расширяют Object, так что нет, никакой разницы не будет. Автобоксирование позволяет использовать примитивы, поэтому можно сказать, что все в java является объектом.

-1
ответ дан 30 November 2019 в 02:27
поделиться

EXACTLY то же самое, что и . Простите, что у меня нет удобной ссылки, но ... это так. :)

EDIT: Конечно, я думал только с определенной точки зрения, когда говорил это. Игнорируйте мой ответ (который был вполне корректно процитирован внизу) и посмотрите на ответы с более высоким рейтингом для реальной истории.

-1
ответ дан 30 November 2019 в 02:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: