1

When I try to cast an object array to a custom data-type (class) array I get the ClassCastException but when I cast an object array to a generics array, no such error is observed; furthermore, if I pass a custom data-type(class) as a type argument, the ClassCastException is not thrown either.

I experimented several things:

  • First, I made a custom data-type called TestClass. Then I tried creating an object array and casting it into TestClass TestClass[] b = (TestClass[]) new Object[100];
    • Result: ClassCastException
  • I made the Main class (the main() function of which is conducting the experiments) accepts type arguments (generics) referred to as Item. This was followed by a line of code this.a = (Item[]) new Object[100]; where a is an instance variable defined as Item[] a.
    • Result: exit code 0
  • Now, I added a line of code to the main(String[] args): Main<TestClass> m = new Main<TestClass>(); do note that I passed TestClass as a type argument so that in the constructor we face a situation almost identical to that in the first experimental setup, therefore I expect a ClassCastException.
    • Result: exist code 0

The entire Main class for further reference (assume TestClass is defined):

public class Main<Item>{
    Item a[];
    TestClass b[];
    public Main(){
        //this.b = (TestClass[]) new Object[100]; (errors disappear when this line is commented out, otherwise ClassCastException is thrown)
        this.a = (Item[]) new Object[100];
    }
    public void doStuff(){
        System.out.println(Arrays.toString(this.a));
        System.out.println(Arrays.toString(this.b));
    }
    public static void main(String[] args) {
        Object a = new Object();
        Main<TestClass> m = new Main<TestClass>(); //TestClass passed as type argument, should cause problems in the constructor
        m.doStuff();
    }

Apologies for not using proper Java conventions, I was only experimenting :)

Shashwat
  • 439
  • 7
  • 13

1 Answers1

2

Because of type erasure: Item is erased to Object, so your code becomes

public class Main {
    Object a[];

    ...
    this.a = (Object[]) new Object[100];
    ...
}

Unsurprisingly that cast succeeds.

Now if you add e.g.

TestClass[] b = m.a;

to main, the compiler will need to insert a cast

TestClass[] b = (TestClass[]) m.a;

and that will fail because m.a is really an Object[].

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487