Consider this hypothetical class (which I found in a online video):
public class Contrived<T extends Number> extends ArrayList<T> {
List <? extends T> values;
......
}
Here the type variables that Contrived
can accept is Number
or some sub-type of Number
. But the class itself inherits from ArrayList
, so what-ever type the class gets, will determine the type of ArrayList
.
Now there is a field called values
, which is List<? extends T values>
. so what does this mean here?
Does the list
can hold anything that extends T
(which in turn extend Number
).
by PECS (producer extends, consumer super)
rule, can I only use this List
to read elements but not add to the list
.
how will the constructor
look like, if I need to pass a list of doubles or some type T
?
You can have a constructor that takes a List<T>
or a List<? extends T>
. Continuing to contrive classes:
class B extends Number{
public double doubleValue() { return 0; }
public float floatValue() { return 0; }
public long longValue() { return 0; }
public int intValue() { return 0; }
}
class C extends B{}
I add a contrived, legal constructor to the Contrived
class, taking a List<? extends T>
:
public Contrived(List<? extends T> values)
{
this.values = values;
}
This allows me to write a main
method such as the following:
public static void main(String[] args)
{
List<C> bList = Arrays.asList(new C(), new C(), new C());
Contrived<B> ci = new Contrived<B>(bList);
}
I can pass a List<C>
into the constructor for a Contrived<B>
.
Another design for the contrived constructor that is legal for Contrived
could be, taking a List<T>
:
public Contrived(List<T> values)
{
this.values = values;
}
Such a constructor doesn't allow a List<C>
for a Contrived<B>
, because now the types must match, as in the following two Contrived
examples:
public static void main(String[] args)
{
List<C> cList = Arrays.asList(new C(), new C(), new C());
Contrived<C> ci = new Contrived<C>(cList); // must match now
}
And
public static void main(String[] args)
{
List<B> bList = Arrays.asList(new B(), new B(), new B());
Contrived<B> ci = new Contrived<B>(bList); // must match now
}