Сложно ...
Для любой переменной типа T
спецификация гласит: http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4
Каждая переменная типа ... имеет ограничение. Если для переменной типа не объявлена граница, предполагается объект.
Можно подумать, что это верно и для подстановочных знаков, и ?
должен быть просто сокращением для ? extends Object
.
И все же, просматривая спецификацию, нет никаких доказательств того, что подстановочный знак должен иметь верхнюю границу (или нижнюю границу). «Неограниченный» ?
трактуется последовательно в отличие от ограниченных подстановочных знаков.
Мы могли бы сделать вывод из правил подтипов, что List<?>
и List<? extends Object>
являются подтипами друг друга, то есть они в основном одного типа.
Но спецификация обрабатывает их отдельно, тем не менее. Например, http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.7 List<?>
- это тип reifiable, но List<? extends Object>
- нет, что означает
// ok
List<?>[] xx = {};
// fail
List<? extends Object>[] yy = {};
// ok
boolean b1 = (y instanceof List<?>);
// fail
boolean b2 = (y instanceof List<? extends Object>);
Хотя я не понимаю, почему. Кажется совершенно правильным сказать, что подстановочный знак должен иметь верхнюю и нижнюю границы, по умолчанию Object
и null type
.