?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>whereXisMyClass,Thread,Runnable,ActionListener,EventListener, orObject.
So, after having read the many answers to the question, here is my
understanding:
? extends Tmeans 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 Tmeans any class / interface which issuperof 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”.