What's the reason Java doesn't allow us to do
private T[] elements = new T[initialCapacity];
I could understand .NET didn't allow us to do that, as in .NET you have value types that at run-time can have different sizes, but in Java all kinds of T will be object references, thus having the same size (correct me if I'm wrong).
What is the reason?
If we cannot instantiate generic arrays, why does the language have generic array types? What's the point of having a type without objects?
The only reason I can think of, is varargs -
foo(T...)
. Otherwise they could have completely scrubbed generic array types. (Well, they didn't really have to use array for varargs, since varargs didn't exist before 1.5. That's probably another mistake.)So it is a lie, you can instantiate generic arrays, through varargs!
Of course, the problems with generic arrays are still real, e.g.
We can use this example to actually demonstrate the danger of generic array.
On the other hand, we've been using generic varargs for a decade, and the sky is not falling yet. So we can argue that the problems are being exaggerated; it is not a big deal. If explicit generic array creation is allowed, we'll have bugs here and there; but we've been used to the problems of erasure, and we can live with it.
And we can point to
foo2
to refute the claim that the spec keeps us from the problems that they claim to keep us from. If Sun had more time and resources for 1.5, I believe they could have reached a more satisfying resolution.The main reason is due to the fact that arrays in Java are covariant.
There's a good overview here.
Quote:
(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
In my case, I simply wanted an array of stacks, something like this:
Since this was not possible, I used the following as a workaround:
Ugly, but Java is happy.
Note: as mentioned by BrainSlugs83 in the comment to the question, it is totally possible to have arrays of generics in .NET
Arrays Are Covariant
This last line would compile just fine, but if we run this code, we would get an ArrayStoreException because we’re trying to put a double into an integer array. The fact that we are accessing the array through a Number reference is irrelevant here, what matters is that the array is an array of integers.
This means that we can fool the compiler, but we cannot fool the run-time type system. And this is so because arrays are what we call a reifiable type. This means that at run-time Java knows that this array was actually instantiated as an array of integers which simply happens to be accessed through a reference of type Number[].
So, as we can see, one thing is the actual type of the object, an another thing is the type of the reference that we use to access it, right?
The Problem with Java Generics
Now, the problem with generic types in Java is that the type information for type parameters is discarded by the compiler after the compilation of code is done; therefore this type information is not available at run time. This process is called type erasure. There are good reasons for implementing generics like this in Java, but that’s a long story, and it has to do with binary compatibility with pre-existing code.
Let’s consider now the following unsafe code:
If the Java compiler does not stop us from doing this, the run-time type system cannot stop us either, because there is no way, at run time, to determine that this list was supposed to be a list of integers only. The Java run-time would let us put whatever we want into this list, when it should only contain integers, because when it was created, it was declared as a list of integers. That’s why the compiler rejects line number 4 because it is unsafe and if allowed could break the assumptions of the type system.
As such, the designers of Java made sure that we cannot fool the compiler. If we cannot fool the compiler (as we can do with arrays) then we cannot fool the run-time type system either.
As such, we say that generic types are non-reifiable, since at run time we cannot determine the true nature of the generic type.
I skipped some parts of this answers you can read full article here: https://dzone.com/articles/covariance-and-contravariance
I like the answer indirectly given by Gafter. However, I propose it is wrong. I changed Gafter's code a little. It compiles and it runs for a while then it bombs where Gafter predicted it would
The output is
So it appears to me you can create generic array types in java. Did I misunderstand the question?