views:

253

answers:

5

Is there ever a difference between an unbounded wildcard e.g. <?> and a bounded wildcard whose bound is Object, e.g. <? extends Object>?

I recall reading somewhere that there was a difference in the early drafts of generics, but cannot find that source anymore.

A: 

Everything in java with the exception of primitives extend Object, so no, there would be no difference. Autoboxing allows the use of primitives so it could be said everything in java is an object.

Malfist
+2  A: 

From experimentation it seems that, for example, List<?> and List<? extends Object> are assignment-compatible both ways, and a method that has a signature using one of them can be overridden with a signature using the other. e.g.,

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);}
}
Chris Jester-Young
Very good, I just upvoted your answer. :-P
Chris Jester-Young
A: 

<? extends Object> is EXACTLY the same as <?>. I'm sorry I don't have a reference handy, but ... it is. :)

EDIT: of course, I was only thinking from a particular perspective when I said that. Ignore my answer (which was quite correctly downvoted) and see the higher-rated answers for the real story.

Kevin Bourrillion
Hey Kevin, good bumping into you. Thanks for looking into the Executors2 thing, much appreciated. :-) Also, feel free to look at my revised entry to "A very average puzzle"; I'd be keen to see what the "official" answer is, and whether my approach is considered "cheating". :-P
Chris Jester-Young
Oh, I can't, because apparently my post was deleted.
Kevin Bourrillion
+9  A: 

From a practical point to most people, <? extends Object> is the same as <?>, like everyone have suggested here.

However, they differ in two very minor and subtle points:

  1. The JVMS (Java Virtual Machine Specification) has a special specification for the unbounded wildcards, as ClassFileFormat-Java5 specifies that unbounded wildcard gets encoded as *, while encodes a Object-bounded wildcard as +Ljava/lang/Object;. Such change would leak through any library that analyzes the bytecode. Compiler writers would need to deal with this issue too. From revisions to "The class File Format"

  2. From reifiablity standpoint, those are different. JLS 4.6 and 4.7 codify List<?> as a reifiable type, but List<? extends Object> as a erasured type. Any library writer adding .isReifiable() (e.g. (mjc lib)[http://www.cs.utep.edu/cheon/ssvl/utjml/mj-javadocs/org/multijava/mjc/CTypeVariable.html]) needs to account for that, to adhere to the JLS terminology. From JLS 4.6 and 4.7.

notnoop
+1, Thanks! Didn't know that! :)
missingfaktor
+6  A: 

As a point of pedntry, there is a difference if the class/interface/constructor/method declares a bound (other than extends Object).

interface Donkey<T extends Thing> { }

...
    Donkey<? extends Object> foo; // FAIL
Tom Hawtin - tackline
Wow! Missed that completely.
notnoop