I am really having a tough time understanding the wild card parameter. I have a few questions regarding that.
?
as a type parameter can only be used in methods. eg: printAll(MyList<? extends Serializable>)
I cannot define classes with ?
as type parameter.
I understand the upper bound on ?
. printAll(MyList<? extends Serializable>)
means: "printAll
will print MyList
if it has objects that implement the Serialzable
interface."
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
)."
Correct me where I went wrong.
In short, only T
or E
or K
or V
or N
can be used as type parameters for defining generic classes. ?
can only be used in methods
public void printAll(MyList<? super MyClass>){
// code code code
}
Accordint to Ivor Horton's book, MyList<? super MyClass>
means that I can print MyList
if it has objects of MyClass
or any of the interfaces or classes it implements. That is, MyClass
is a lower bound. It is the last class in the inheritance hierarchy. This means my initial assumption was wrong.
So, say if MyClass
looks like:
public class MyClass extends Thread implements ActionListener{
// whatever
}
then, printAll()
will print if
1. There are objects of MyClass
in the list
2. There are objects of Thread
or ActionListener
in the List
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
?
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 issuper
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".