user12618962
user12618962

Reputation:

Create array of generic type of class

For class we have to implement data structures in java without using those already implemented by default, so no I cannot use Lists. Previously there were situations where it was necessary to create an array of a generic type T and the following works without problem:

class Test<T> {
  private T[] array;

  @SuppressWarnings("unchecked")
  public Test(int sz) {
    array = (T[]) new Object[sz];
  }

  public static void main(String[] args) {
    Test test = new Test(1);
  }
}

Now instead of an array of type T, it was necessary to create an array of type Thing<T> where Thing is a class... The same approach gives runtime error (java.lang.ClassCastException):

class Thing<T> { }

class Test<T> {
  private Thing<T>[] array;

  @SuppressWarnings("unchecked")
  public Test(int sz) {
    array = (Thing<T>[]) new Object[sz];
  }

  public static void main(String[] args) {
    Test<Object> test = new Test<>(1);
  }
}

What can be done about the second case?

Upvotes: 2

Views: 120

Answers (3)

newacct
newacct

Reputation: 122429

When you cast Object[] to T[], it is a lie because it is incorrect if T is anything other than Object. However, it does not cause a class cast exception inside the class because the inside of the class is within the scope of the type variable T, so the type of the variable array, T[], is erased to Object[] at runtime, so casting Object[] to it does not fail (though if you somehow expose the array to the outside of the class as type T[], the outside caller may get a class cast exception).

If T had an upper bound like <T extends MyClass>, then the erasure of T[] would be MyClass[], so casting Object[] to it would immediately throw a class cast exception, and you would have to do new MyClass[sz] for it to not immediately throw a class cast exception.

Here, the variable is of type Thing<T>[], the erasure of which is Thing[]. So you would have to create an array with new Thing[sz] for it not to throw a class cast exception.

Upvotes: 0

Adwait Kumar
Adwait Kumar

Reputation: 1604

You are trying to cast a list of Object to Thing which an Object is not, so it will not work.

The problem you are facing is that in Java you can't instantiate an array of generic types.

So instead create an array of raw type Thing[] and cast it to generic type Thing<T>[], which is OK in this case given that there is type erasure happening anyways.

class Thing<T> {
}

class Test<T> {
    private Thing<T>[] array;

    @SuppressWarnings("unchecked")
    public Test(int sz) {
        array = (Thing<T>[]) new Thing[sz];
    }

    public static void main(String[] args) {
        Test<Object> test = new Test<>(1);
    }
}

Upvotes: 2

Priyam
Priyam

Reputation: 148

Try this:

public class Thing<T> {
}

class Test<T> {
    private Thing<T>[] array;

    @SuppressWarnings("unchecked")
    public Test(int sz) {
        array = (Thing[]) Array.newInstance(Thing.class, sz);
    }

    public static void main(String[] args) {
        Test<Object> test = new Test<>(1);
    }
}

You can further refer here

Upvotes: 0

Related Questions