I have the following code within a program I’m making:
01 public class Clazz<T>
02 {
03 T[] t;
04
05 public Clazz<T> methodA(int... ints)
06 {
07 Clazz<Integer> ints2 = new Clazz<>();
08 int remInd[] = new int[t.length - ints2.t.length];
09 return this;
10 }
11 }
but when I run method methodA, I get this error:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
at Clazz.methodA(Clazz.java:8)
Why would I get this error? Of course, the code I’ve shown is incomplete compared to the huge class in question (for instance, the array t won’t be empty when checking its length), but I believe I’ve shown everything that matters. Why won’t this run?
A note: I am making this with JDK 1.7, so that’s why line 7 compiles and works
Working Solution
I decided, for whatever reason, to implement the following solution, and it worked:
01 public class Clazz<T>
02 {
03 T[] t;
04
05 public Clazz<T> methodA(int... ints)
06 {
07 Clazz<Integer> ints2 = new Clazz<>();
08 int remInd[] = new int[t.length - ints2.length()];
09 return this;
10 }
11
12 public int length()
13 {
14 return t.length;
15 }
16 }
Though this is a solution, I would still like to know why it works.
You are missing the code that initializes
T, but I’m going to assume it looks something like this. I’ve added a few lines that don’t change any functionality but which will help demonstrate the error:With this code I could reproduce the error. The problem here is in this code:
Since the compiler knows the type parameter for
ints2and thusints2.t, this can be thought of as the rough equivalent of this:It is in the implicit cast to
Integer[](whose class simple name is[Ljava.lang.Integer) that this fails, sincetis anObject[]and not anInteger[], and one cannot be cast to the other.Working with generic arrays
There are many complications from working with arrays declared over a generic type that are documented elsewhere. In short, I’ll say that if you need to have a “generic array” instead consider declaring and using it as an
Object[]in every way, except that when you interact with a client of the class, you either accept or return only aTinstead of anObject(for returning, via an unchecked cast). For example,This is how
ArrayListworks, by the way. Have a look at its code on DocJar.Edit
Generic arrays aside, I don’t think you understand the idea of the implicit cast. Here’s much shorter code that fails with essentially the same error:
Even though there is no need to cast
clazz.tto a String, it does so implicitly simply by referencingclazz.t. Here is thejavap -coutput for that compiled class:In the case of your original code, here is the
javap -coutput ofmethodA():