2

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?

11
  • 2
    Instead of doing array = (Thing<T>[]) new Object[sz];, why can't you just do array = new Thing[sz]; ? Commented Dec 29, 2019 at 14:33
  • @AshishkumarSingh I can... but why? Commented Dec 29, 2019 at 14:44
  • Does this answer your question? How to create a generic array in Java? Commented Dec 29, 2019 at 15:15
  • @Priyam I believe not. That question seems to ask to create an array of a type T , not an array of type SomeClass<T>. Commented Dec 29, 2019 at 15:19
  • @CarlaCvekla Your attempted casting is the equivalent of "This array of objects is actually an array of things", to which the JVM then says "no it's not" and throws a ClassCastException. So you would use new Thing[sz] because it's correct. Commented Dec 29, 2019 at 15:22

3 Answers 3

2

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);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Is there any reason to cast the new Thing[sz] to Thing<T>[] though? It seems to work even without the cast.
@CarlaCvekla, no it's essentially the same. In one case it is an unchecked cast and in other it is an unchecked assignment.
0

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

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.