I understand that you cannot bind a generics Java type parameter to the lower bound (i.e. using the super keyword). I read that Angelika Langer Generics FAQ on this . They say that it basically boils down to the fact that the lower bound is useless ("makes no sense").
I'm not sure. I can imagine using them to help you be more flexible for library calling methods that create a typed result. Imagine a method that created a list of arrays of a user-defined size and filled it with an empty string. A simple announcement would be
public static ArrayList<String> createArrayListFullOfEmptyStrings(int i);
But this is unnecessarily restrictive for your customers. Why they cannot call your method as follows:
//should compile List<Object> l1 = createArrayListFullOfEmptyStrings(5); List<CharSequence> l2 = createArrayListFullOfEmptyStrings(5); List<String> l3 = createArrayListFullOfEmptyStrings(5); //shouldn't compile List<Integer> l4 = createArrayListFullOfEmptyStrings(5);
At this point, I will be tempted to try the following definition:
public static <T super String> List<T> createArrayListFullOfEmptyStrings(int size) { List<T> list = new ArrayList<T>(size); for(int i = 0; i < size; i++) { list.add(""); } return list; }
But it will not compile; The super keyword is illegal in this context.
My example is above a bad example (ignoring what I say below)? Why is there no bottom line? And if that would be useful, what is the real reason that Java is not allowed?
PS
I know that a better organization might be something like this:
public static void populateListWithEmptyStrings(List<? super String> list, int size); List<CharSequence> list = new ArrayList<CharSequence>(); populateListWithEmptyStrings(list, 5);
For this purpose, can we pretend that, on demand, we need to perform both operations in one method call?
Edit
@Tom G (rightly) asks what advantage List<CharSequence> for List<String> . Firstly, no one said that the returned list is immutable, so here is one advantage:
List<CharSequence> l2 = createArrayListFullOfEmptyStrings(5); l2.add(new StringBuilder("foo").append("bar"));