Java generics: wildcard<?> vs type parameter?

前端 未结 3 889
孤城傲影
孤城傲影 2020-12-04 16:59

I am refreshing my knowledge on Java generics. So I turned to the excellent tutorial from Oracle ... and started to put together a presentation for my coworkers. I came acro

3条回答
  •  一向
    一向 (楼主)
    2020-12-04 17:21

    Your approach of using a generic method is strictly more powerful than a version with wildcards, so yes, your approach is possible, too. However, the tutorial does not state that using a wildcard is the only possible solution, so the tutorial is also correct.

    What you gain with the wildcard in comparison to the generic method: You have to write less and the interface is "cleaner" since a non generic method is easier to grasp.

    Why the generic method is more powerful than the wildcard method: You give the parameter a name which you can reference. For example, consider a method that removes the first element of a list and adds it to the back of the list. With generic parameters, we can do the following:

    static  boolean rotateOneElement(List l){
        return l.add(l.remove(0));
    }
    

    with a wildcard, this is not possible since l.remove(0) would return capture-1-of-?, but l.add would require capture-2-of-?. I.e., the compiler is not able to deduce that the result of remove is the same type that add expects. This is contrary to the first example where the compiler can deduce that both is the same type T. This code would not compile:

    static boolean rotateOneElement(List l){
        return l.add(l.remove(0)); //ERROR!
    }
    

    So, what can you do if you want to have a rotateOneElement method with a wildcard, since it is easier to use than the generic solution? The answer is simple: Let the wildcard method call the generic one, then it works:

    // Private implementation
    private static  boolean rotateOneElementImpl(List l){
        return l.add(l.remove(0));
    }
    
    //Public interface
    static void rotateOneElement(List l){
         rotateOneElementImpl(l);
    }
    

    The standard library uses this trick in a number of places. One of them is, IIRC, Collections.java

提交回复
热议问题