I've heard here and there that arrays contain runtime data about their type, making you unable to instantiate an E[]
(E
being a generic type parameter, for example in a class Foo<E>
), and that while you can achieve the same effect by doing (E[]) new Object[n]
, it is bad, which is why the compiler raises a warning. I'm having trouble thinking of what exactly could go wrong (famous last words), so could someone give an example of how a program could become defective because of instantiating Object[]
s and casting them to E[]
?

- 758
- 7
- 14
-
You might want to edit to indicate that E is a generic type parameter. – Erik Eidt Sep 15 '16 at 01:49
-
2[What is the X Y Problem?](http://meta.stackexchange.com/a/66378) – Robert Harvey Sep 15 '16 at 02:43
-
@RobertHarvey My problem is my computer science professor telling his class to create E[] by casting Object[] – Phoenix Sep 15 '16 at 02:47
-
1Do what your teacher says to pass the class. Do it the right way later. See also http://stackoverflow.com/a/30096771 – Robert Harvey Sep 15 '16 at 02:53
-
He's not requiring us to do that, he's just suggesting it as a good practice. – Phoenix Sep 15 '16 at 02:57
-
The question maybe should at least contain the word Java – yeoman Sep 15 '16 at 06:03
-
It is quite an interesting question though, because this exact kind of problem is common when you implement most kinds of collections in Java. – yeoman Sep 15 '16 at 06:04
-
[Why following types are reifiable& non-reifiable in java?](http://stackoverflow.com/q/18848885) – Sep 19 '16 at 23:57
2 Answers
If the array is only used within the inside of the class, and the fact of the variable's type as E[]
is never exposed outside the class (e.g. returned in a method, or it is a public or protected field, etc.), then there is no problem as inside the class E
is erased.
However, if you expose the fact of the array variable's type as E[]
to the outside of the class, then it can go into a context where they have a concrete type for your E
, and rightly believe that what they are getting is that type of array, and it will throw a ClassCastException
without any warning in that outside code. The simplest example is a method that simply returns the array as E[]
, and it is called from outside code that has a concrete type as the type parameter; a ClassCastException
is thrown from the outside code without any warning in that outside code or in the method that returns the array:
public class Foo<E> {
private E[] myArray = (E[])new Object[42];
public E[] getArray() {
return myArray;
}
}
// some outside code:
Foo<String> foo = new Foo<String>();
String[] stringArray = foo.getArray(); // ClassCastException

- 510
- 2
- 8
-
I'd like to point out that if instead `Foo` was declared as `class Foo
` then `E[] myArray = (E[]) new Object[42];` would also throw a `ClassCastException` because the type erasure of the `myArray` field would be `Runnable[]`, an array of the first extended class/interface in the declaration. – gary Nov 06 '22 at 12:29 -
@gary: Correct. You would create it as `(E[]) new
[42]`, which in your example, would be `(E[]) new Runnable[42]` – user102008 Nov 06 '22 at 16:12
You could, of course, declare the array as Object[], and write a private accessor like
Object[] elements = ...;
@SuppressWarnings("unchecked")
private E getElement(int index)
{
return (E)elements[index];
}
This way, you don't have a field with declaration that lies to you and every other reader of your code, and confine the cast to a single place. The cast is a no-op, btw., because there's no way for the compiler to do a real actual cast to a non-reified type.
This is in fact exactly what goes on inside many well-written collection implementations.
The cast to E[] can have performance benefits for a real actual collection, so it is the way to go in those few places where you write code that influences lots of other code, performance-wise.
Use comments, because exceptional things are the one area where they can be valuable. Restrain the field's scope. Think thrice about what you're doing in any step, and you should be fine :)
In case performance is NOT paramount, though, just use the accessor

- 373
- 2
- 6
-
I just looked inside a collection I've recently written, and I also used a cast to E[] – yeoman Sep 15 '16 at 06:07
-
-
Nope, i take that back. There's been performance reasons for casting to E[]. So just be careful about it :) – yeoman Sep 15 '16 at 06:09