Java Generics bounded wild card usages before the return type of a method

JavaNovice :

In the class below, in method m1, is there really any use of mentioning K extends Runnablebefore the method return type? I cannot return anything other than Collection<K> anyways. And if I want to return any subclass of Runnable I would have specified the method like,

static <T> Collection<? extends Runnable> m1(ArrayList<T> l)

Does the K extends Runnable before the method return type have any significance at all? I get no compilation error for this code either

public class MainClass {
    public static void main(String[] args) {
        ArrayList<Thread> l = new ArrayList<>();
        l.add(new Thread());
        l.add(new Thread());
        m1(l);
    }

     static <T, K extends Runnable> Collection<K> m1(ArrayList<T> l) {
        ArrayList<K> r = new ArrayList<>();
        return r;
    }
}
Thilo :

By having the parameter K, you can let the caller decide what kind of collection it wants back:

public class Test {
    static <T, K extends Runnable> Collection<K> m1(ArrayList<T> l) {
        ArrayList<K> r = new ArrayList<>();
        return r;
    }

    static void callingIt(){
        ArrayList<?> list = new ArrayList<>();
        Collection<Thread> threads = m1(list);
        Collection<Runnable> runnables = m1(list);
        Collection<MyTask> special = m1(list);

    }

    class MyTask extends Thread{}
}

If you only had Collection<? extends Runnable> then the caller cannot get back a Collection<Thread>.

But unless the K is connected to something else, I cannot see how this would work except for empty result lists (because as soon as you want to add something to r, you will have to make sure it is an instance of K).


You can see this pattern being used in Collections.emptyList:

public static final List EMPTY_LIST = new EmptyList<>();

public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}

The method returns the same thing as the field, but because it is a method, the caller can use it to produce generically typed lists of any type (whereas the field cannot be flexible like this).

There is an unchecked cast in there (with a warning), but since the list is empty, we (unlike the compiler) know it is safe.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=142496&siteId=1