3

I just stumbled upon the following overloads of sort in java.util.Arrays:

public static void sort(Object[] a)

public static <T> void sort(T[] a, Comparator<? super T> c)

Why is the first overload not generic, but the second one is? Why does the first overload take an Object[] instead of a Comparable[]? The documentation even states:

All elements in the array must implement the Comparable interface.

So what's the point of not verifying that constraint with Java's static type system?

4
  • 4
    Maybe the first one existed before generics were introduced? Commented Jun 5, 2013 at 9:08
  • 1
    @Oli It could still have taken a Comparable[] before generics, right? Commented Jun 5, 2013 at 9:11
  • Note that TreeSet has the same "bizzareness": you can actually created a TreeSet with a class not implementing Comparable, but then at runtime you'll get ClassCastException. Arrays are another problem though, since A[] is not the same as B[] at runtime, unlike genericized collections. Commented Jun 5, 2013 at 9:18
  • @fge: i think it is for compatibility reasons that TreeSet takes elements that do not implement Comparable if you provide a Comparator Commented Jun 5, 2013 at 9:21

2 Answers 2

3

The first method could be better if it were generic, but it would break compatibility with pre 1.5 code:

static <T extends Comparable<T>> void sort(T[] a) {
    ...
}

static void main(String[] args) {
   Object[] a = {"1", "2"};
   sort(a); <- compile time error, need explicit cast sort((Comparable[])a);
}

While the second one compiles with 1.4 code with warning only

public static <T> void sort(T[] a, Comparator<? super T> c) {
    ...
}

public static void main(String[] args) throws Exception {
    Object[] a = { "1", "2" };
    sort(a, new Comparator() {   <-- warning 
        @Override
        public int compare(Object o1, Object o2) {
            return 0;
        }
    });
}
Sign up to request clarification or add additional context in comments.

Comments

2

The first one method (void sort(Object[] a)) is not generic because:

  1. it was introduced before generics appear in Java
  2. it actually doesn't need generics

The second one requires generics, I think, only due to this construction Comparator<? super T>, because there isn't another convenient way to declare restrictions under second parameter with Comparator class.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.