If generic array creation were legal, then compiler generated casts would correct the program at compile time but it can fail at runtime, which violates the core fundamental system of generic types.
Java allows generic classes, methods, etc. that can be declared independent of types. However, Java does not allow the array to be generic. The reason for this is that in Java, arrays contain information related to their components and this information is used to allocate memory at runtime.
Almost all reference types can be generic. This includes classes, interfaces, nested (static) classes, nested interfaces, inner (non-static) classes, and local classes. The following types cannot be generic: Anonymous inner classes .
To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class. As you can see, all occurrences of Object are replaced by T.
It's because Java's arrays (unlike generics) contain, at runtime, information about its component type. So you must know the component type when you create the array. Since you don't know what T
is at runtime, you can't create the array.
Quote:
Arrays of generic types are not allowed because they're not sound. The problem is due to the interaction of Java arrays, which are not statically sound but are dynamically checked, with generics, which are statically sound and not dynamically checked. Here is how you could exploit the loophole:
class Box<T> { final T x; Box(T x) { this.x = x; } } class Loophole { public static void main(String[] args) { Box<String>[] bsa = new Box<String>[3]; Object[] oa = bsa; oa[0] = new Box<Integer>(3); // error not caught by array store check String s = bsa[0].x; // BOOM! } }
We had proposed to resolve this problem using statically safe arrays (aka Variance) bute that was rejected for Tiger.
-- gafter
(I believe it is Neal Gafter, but am not sure)
See it in context here: http://forums.sun.com/thread.jspa?threadID=457033&forumID=316
By failing to provide a decent solution, you just end up with something worse IMHO.
The common work around is as follows.
T[] ts = new T[n];
is replaced with (assuming T extends Object and not another class)
T[] ts = (T[]) new Object[n];
I prefer the first example, however more academic types seem to prefer the second, or just prefer not to think about it.
Most of the examples of why you can't just use an Object[] equally apply to List or Collection (which are supported), so I see them as very poor arguments.
Note: this is one of the reasons the Collections library itself doesn't compile without warnings. If you this use-case cannot be supported without warnings, something is fundamentally broken with the generics model IMHO.
The reason this is impossible is that Java implements its Generics purely on the compiler level, and there is only one class file generated for each class. This is called Type Erasure.
At runtime, the compiled class needs to handle all of its uses with the same bytecode. So, new T[capacity]
would have absolutely no idea what type needs to be instantiated.
The answer was already given but if you already have an Instance of T then you can do this:
T t; //Assuming you already have this object instantiated or given by parameter.
int length;
T[] ts = (T[]) Array.newInstance(t.getClass(), length);
Hope, I could Help, Ferdi265
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With