?
as a type parameter can only be used in methods. eg: printAll(MyList<? extends Serializable>)
I cannot define classes with ?
as type parameter.
A wildcard (?
) isn't a formal type parameter, but rather can be used as a type argument. In the example you give, ? extends Serializable
is given as a type argument to the generic type MyList
, of the printAll
method's parameter.
Methods can also declare type parameters like classes, for example:
static <T extends Serializable> void printAll(MyList<T> myList)
I understand the upper bound on ?
. printAll(MyList<? extends Serializable>)
means printAll will print MyList if it has objects that implement the Serialzable interface
More accurately, it means a call to printAll
will compile only if it is passed a MyList
with some generic type that is or implements Serializable
. In this case it would accept a MyList<Serializable>
, MyList<Integer>
, etc.
I have a bit of an issue with the super
. printAll(MyList<? super MyClass>)
means printAll will print MyList if it has objects of MyClass or any class which extends MyClass (the descendants of MyClass)
A wildcard bounded with super
is a lower bound. So we could say a call to printAll
will compile only if it is passed a MyList
with some generic type that is MyClass
or some super-type of MyClass
. So in this case it would accept MyList<MyClass>
, e.g. MyList<MyParentClass>
, or MyList<Object>
.
So, say if MyClass looks like:
public class MyClass extends Thread implements ActionListener{
// whatever
}
then, printAll() will print if
- There are objects of MyClass in the list
- There are objects of Thread or ActionListener in the list
You're on the right track. But I think saying e.g. "it will print if there are objects of MyClass
in the list" is problematic. That makes it sound like you're defining runtime behavior - generics are all about compile time checks. For example wouldn't be able to pass a MyList<MySubclass>
as an argument for MyList<? super MyClass>
, even though it might contain instances of MyClass
, by inheritance. I would reword it to:
A call to printAll(MyList<? super MyClass>)
will compile only if it is passed a:
MyList<MyClass>
MyList<Thread>
MyList<Runnable>
MyList<ActionListener>
MyList<EventListener>
MyList<Object>
MyList<? super X>
where X
is MyClass
, Thread
, Runnable
, ActionListener
, EventListener
, or Object
.
So, after having read the many answers to the question, here is my
understanding:
? extends T
means any class which extends T. Thus, we are referring to
the children of T. Hence, T is the upper bound. The upper-most class
in the inheritance hierarchy
? super T
means any class / interface which is super
of T. Thus we are
referring to all the parents of T. T is thus the lower bound. The
lower-most class in the inheritance hierarchy
Close, but I wouldn't say "children of T
" or "parents of T
", since these bounds are inclusive - it would be more accurate to say "T
or its subtypes", and "T
or its supertypes".