-1

I am new to java and I have this cast for some public class MergeSort<Item>

Integer N = Integer.valueOf(StdIn.readString());   
MergeSort<Integer>[] input = (MergeSort<Integer>[]) new Object[N];

and I get this :

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [LMergeSort;
user1611830
  • 4,209
  • 7
  • 47
  • 79

1 Answers1

1

This doesn't work because you're trying to cast an array to an array subtype of its class. You would get the same error from the code:

Integer[] input = (Integer[]) new Object[N];

Why doesn't this work? Because the original array is set to allow any object in it. It's not allowed because retrieving elements from an array (within the size of the array) is supposed to always work. The error prevents the following sort of thing:

Object[] arr = new Object[1];
arr[0] = "Hello, world!";
Integer[] input = (Integer[]) arr; //Runtime error here
Integer i = input[0]; //This operation is supposed to never throw an error, but it would if one hadn't been thrown earlier.

"But in my code, the array is immediately cast to my subtype of Object, and can never receive any other type of object." Not so! If your cast was allowed, the following would be valid:

MergeSort[] input = (MergeSort[]) new Object[N]; //Runtime error here
Object[] arr = input; //Casting to supertype is valid; inserting wrong elements is checked by ArrayStoreException
arr[0] = "Not a MergeSort!"; //Valid because array was originally constructed as an Object[]
MergeSort m = input[0]; //Supposed to always work, but can't possibly work.

"Wait, why did you take out the from my MergeSort?" See this question. In short, at runtime, a MergeSort is indistinguishable from a MergeSort and every other sort of MergeSort, therefore, again to prevent you from attempting to retrieve one class of object from an array but instead receiving another, it is impossible to specify generics in your array creation. Instead, establish a contract that all elements in the array must be MergeSort, and cast your retrievals from the array to MergeSort. For a non-local variable, you could do it like this:

private MergeSort[] input = ...;
public MergeSort<Integer> getMergeSort(int pos) {
    return (MergeSort<Integer>) input[pos]; //Compiler warning here because it could throw an error if the contract of setMergeSort(...) is not followed.
}
public void setMergeSort(int pos, MergeSort<Integer> mergeSort) {
    input[pos] = mergeSort;
}
Community
  • 1
  • 1
Vitruvie
  • 2,281
  • 16
  • 24