Thank Raymond for showing me the concerning code (andReturn), I feel SCA has
quite some misusages of <?> on Generic and compilers failing to complain
have defect(s).
Someone may want to open defect against corresponding compiler, I'll just
focus on illustrating the <?> misusage.
andReturn itself is declared in a Generic class:
class MyClass<T>
{
andReturn(T)
}
that's fine, however it's instantiated as
var = new MyClass<?>
or
class ChildClass extends MyClass<?>
therefore the signature becomes
andReturn(?)
No matter such signature comes from instantiation or original design, it may
be caused by misunderstanding of <?>.
<?> denotes *some* type, *not* any type which Object does.
Some type means some type, neither specifically String nor specifically
ArrayList, therefore
andReturn("bar")
is a *invalid* call and all compilers are supposed to catch that error which
is one of the beauties to introduce Generic.
For API design who wants any type instead of some type, Object can be used
or use *no* parameter to instantiate Generic such as
var = new MyClass
and
class ChildClass extends MyClass
Similarly, Bounded Wildcards is also *some* bounded type, *not* any bounded
type.
e.g. "? extends List" denotes some List subclass, not any List subclass.
I'm also pasting a paragraph for your reference, from
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
Collection<?> c = new ArrayList<String>();
c.add(new Object()); // compile time error
Since we don't know what the element type of c stands for, we cannot add
objects
to it. The add() method takes arguments of type E, the element type of the
collection.
When the actual type parameter is ?, it stands for some unknown type. Any
parameter
we pass to add would have to be a subtype of this unknown type. Since we
don't know
what type that is, we cannot pass anything in. The sole exception is null,
which is a
member of every type.
--
Yang ZHONG