Generic class and interface declarations want type parameters, such as T or U. ? is a wildcard, better used for method parameters that are themselves generic:
class Foo<T extends Number & List> {
void doStuff(List<T> items) {
// ...
}
void doMoreStuff(List<? extends OutputStream> streams) {
// ...
}
}
doStuff() indicates that it wants to operate on a List<T>
where T is the type parameter on class Foo. So:
class Weird extends Number implements List {
//
}
Foo<Weird> f = new Foo<Weird>();
f.doStuff(...); // wants a List<Weird>
If we called doMoreStuff() on f, we could hand it something of type List<OutputStream>
, List<FilterOutputStream>
, List<ByteArrayOutputStream>
, etc.