Search code examples
javagenerics

Explanation of a Generic code snippet from oracle JAVA Docs


The below code snippet is from oracle docs: I have a few doubts about the syntax. Need proper and detailed explanation.

Write a generic method to find the maximal element in the range [begin, end) of a list.

public final class Algorithm {
    public static <T extends Object & Comparable<? super T>>
        T max(List<? extends T> list, int begin, int end) {

        T maxElem = list.get(begin);

        for (++begin; begin < end; ++begin)
            if (maxElem.compareTo(list.get(begin)) < 0)
                maxElem = list.get(begin);
        return maxElem;
    }
}
  1. Why does the method type parameter <T extends Object & Comparable<? super T>> T has to extend both Object and Comparable. What will be the issue or difference if it were just <T extends Comparable<? super T>>?
  2. Why does the type parameter for Comparable<? super T> cannot be just Comparable<T>?
  3. What would be the difference if the type parameter for List were just List<T> instead of List<? extends T>?

Solution

    1. For the most part, Object is redundant here. See this post for more info.

    2. If you constrain it to only T extends Comparable<T>, that means if I have a Dog that can be compared to any Animal (Dog implements Comparable<Animal>), and I want the method to give me the "maximum" Dog in a list of Dogs (I should be able to do this), the method will return an Animal instead. T can't be Dog, since Dog does not implement Comparable<Dog>.

      Saying Comparable<? super T> allows Ts that implement Comparable<SomeSuperclassOfT> to be used.

    3. This is similar to 2. If you make it List<T>, then I can't give you a List<Dog> and ask you to return an Animal (T can't be Animal if I pass a List<Dog>). However, as far as I can tell, this doesn't really affect much in practice, because I can still convert the returned Dog to an Animal if I want.