1

I wrote a java program for MergeSort using java generics. However I get following errors, I don't understand where I have gone wrong. please Help me out

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable; at src.MergeSort.sort(MergeSort.java:9) at src.MergeSort.main(MergeSort.java:57)

package src; import java.util.Arrays;

public class MergeSort {

  // sort array of type T using the Mergesort algorithm
  public static <T extends Comparable<T>> T[] sort(T[] arr) {
  if (arr.length > 1){
      T[] firstHalf =  (T[]) new Object[arr.length/2];
      System.arraycopy(arr, 0, firstHalf, 0, arr.length /2);
      sort(firstHalf);

 int secondHalfLength = arr.length -arr.length/2;
 T[] secondHalf = (T[]) new Object[secondHalfLength];
 System.arraycopy(arr, arr.length/2, secondHalf, 0, secondHalfLength);
 sort(secondHalf);
 merge(firstHalf, secondHalf, arr);

  }


      return arr;
  }

  public static <T extends Comparable<T>> void merge(T[] arr1, T[] arr2, T[] temp) {
  int current1 = 0;
  int current2 = 0;
  int current3 = 0;

  while(current1 < arr1.length && current2 < arr2.length){
      if (arr1[current1].compareTo(arr2[current2]) < 0)
          temp[current3++] = arr1[current1++];
      else
          temp[current3++] = arr2[current2++];

          }

  while (current1 < arr1.length)
  temp[current3++] = arr1[current1++];
  while (current2 < arr2.length)
  temp[current3++] = arr2[current2++];


  }




  public static void main(String[] args) {



// sort list of Characters
Character[] charArr = {'H','e','l','l','o',' ','w','o','r','l','d','!'};

charArr = MergeSort.<Character>sort(charArr);
System.out.println(Arrays.toString(charArr));

// sort list of Integers
Integer[] intArr = {23,4,15,8,42,16};

intArr = MergeSort.<Integer>sort(intArr);
System.out.println(Arrays.toString(intArr));
      }
    }
4
  • Why are you instantiating Object[]? Commented May 22, 2014 at 9:20
  • You have an object in your Array that is not implementing comparable interface Commented May 22, 2014 at 9:21
  • because I couldn't create new generics array using T[] firstHalf = new T[arr.length/2]; Commented May 22, 2014 at 9:22
  • so how do I create new generics array for firstHalf Commented May 22, 2014 at 9:23

1 Answer 1

4

Long story short, it's because your type parameter is actually being erased to Comparable.

Remember, generics are erased to their bounding type. In most cases, where there is no bounding type, type parameters would be erased to Object, but here, because you're bounding T by Comparable, T is erased to Comparable. Thus, casts like this:

T[] firstHalf =  (T[]) new Object[arr.length/2];

Become

Comparable[] firstHalf = (Comparable[]) new Object[arr.length / 2];

And because Object doesn't implement Comparable, the cast fails at runtime.

The solution? Simply make your arrays Comparable[]. Then your cast won't fail at runtime.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. I used T[] firstHalf = (T[]) new Comparable [arr.length/2]; instead of T[] firstHalf = (T[]) new Object[arr.length/2]; and it worked
However I get "Type safety: Unchecked cast from Comparable[] to T[]" do you know what does that mean or how can I avoid it. Thanks
@user3612693 That's unfortunately a byproduct of how generics were implemented in Java. It means that the compiler cannot prove that the cast will not throw a ClassCastException at runtime. If you implemented your generics right, you should be able to prove to yourself that the cast is always safe, and so you can stick a @SuppressWarnings("unchecked") onto the assignment. If you take a look at Java's Collections framework, you can see that the same method is used there.

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.