Есть ли когда-либо различие между неограниченным подстановочным знаком, например. <?>
и ограниченный подстановочный знак, чей связанный Object
, например. <? extends Object>
?
Я вспоминаю чтение где-нибудь, что было различие в ранних проектах дженериков, но не может больше находить тот источник.
В качестве точки опоры для педантизма, есть разница, если класс/интерфейс/конструктор/метод декларирует границу (кроме расширяет Object
).
interface Donkey<T extends Thing> { }
...
Donkey<? extends Object> foo; // FAIL
Из экспериментов кажется, что, например, List >
и List extends Object>
совместимы с присваиванием в обоих случаях, и метод, имеющий подпись, использующую одну из них, может быть переопределен подписью, использующей другую,
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);}
}
С практической точки зрения для большинства людей, extends Object>
является тем же самым, что >
, как все предлагали здесь.
Однако, они отличаются двумя очень малыми и тонкими моментами:
JVMS (Java Virtual Machine Specification) имеет специальную спецификацию для неограниченных подстановочных знаков, так как ClassFileFormat-Java5
указывает, что неограниченный подстановочный знак кодируется как *
, в то время как Объектный подстановочный знак кодируется как +Ljava/lang/Object;
. Такое изменение просочится через любую библиотеку, которая анализирует байткод. Авторам компиляторов тоже нужно будет разобраться с этой проблемой. С редакций до "The class File Format"
С точки зрения повторяемости, они отличаются. JLS 4.6 и 4.7 кодифицируют List>
как тип с возможностью повторной модификации, но List расширяет Object>
как стертый тип. Любой библиотечный писатель, добавляющий .isReifiable()
(например, mjc lib) должен учитывать это, чтобы придерживаться терминологии JLS. Из JLS 4.6 и 4.7.
Все в java за исключением примитивов расширяют Object, так что нет, никакой разницы не будет. Автобоксирование позволяет использовать примитивы, поэтому можно сказать, что все в java является объектом.
extends Object>
EXACTLY то же самое, что и >
. Простите, что у меня нет удобной ссылки, но ... это так. :)
EDIT: Конечно, я думал только с определенной точки зрения, когда говорил это. Игнорируйте мой ответ (который был вполне корректно процитирован внизу) и посмотрите на ответы с более высоким рейтингом для реальной истории.