4

Now, I've seen many similar questions to this or this before and I understand the answer is "because of erasure". But I don't understand why erasure prevents us creating an array of generics.

As far as I understand; arrays represent a contiguous allocation of memory, containing primitives or references to objects. Unless I'm mistaken, java arrays are little more than C/C++ arrays with a bit of fancy dressing around them. Is this correct?

If so, why does erasure prevent an array being created like this for generic types? Aren't all references the same size, regardless of the type of the class? The class of course would be bigger or smaller, but that shouldn't affect the reference. So wouldn't we know exactly how big the array should be?

Or is it technically possible to do, but some other problem is encountered if we allow generic arrays to be created?


To be clear: I understand what erasure is and how it works. I understand how I can create an array, given the above restrictions. I don't want to do this.

I just want to understand for what reason the type information is required when I create an array.

6
  • It is possible to create a generic array, only the Java compiler will not know it is an array of a that generic type anymore. Commented May 27, 2015 at 3:13
  • Why: because "erasure" means the type is erased, so it's not available at runtime. Commented May 27, 2015 at 3:35
  • see stackoverflow.com/questions/2927391/… Commented May 27, 2015 at 3:43
  • I understand what "erasure" means. I'm asking why is the type information important in this situation? What does it provide, that I can't do without when I create an array? Commented May 27, 2015 at 5:05
  • 2
    java associate component type with an array object. so a String[] object is associate with String.class. why? because covariance. why? well... I like how @raxod502 puts it - "the whole thing is rather a comedy of errors in the Java design" stackoverflow.com/a/2927415/2158288 Commented May 27, 2015 at 5:32

2 Answers 2

0

You are mistaken. Arrays in Java have type information encoded in them. The array itself is an object and a type. You can make a String[] and call wait() and toString() on it, and that type is distinct from the String type. There is not one array type, each type is distinct. You can call getClass() on a String[] and it will return a different class than any other type of array.

So if the type it self is erased (that's what "erasure" means) there there's no type to make a T or whatever.

So you have to fake it with Object[] which will store any type but isn't actually a specific type.

You can however make an array type reflectively. Call

Array.newInstance( t.getClass(), <dim> );

and you can make a specific type of array, as long as t is the right type.

Sign up to request clarification or add additional context in comments.

8 Comments

I understand what the erasure part means, and even the fact that Arrays have extra information encoded within them (hence the "with a bit of fancy dressing around them"). All of the info that you've mentioned (with the exception of getClass) isn't related to the type, though. So, with the exception of getClass (for which there's numerous workarounds), what does the array actually need from the type information?
I don't think you do understand erasure or that "fancy bit of dressing". Java is a strongly typed language. It does not allow you to assign String[] to Integer[] or vice-versa. It needs the type -- the thing that got erased -- to make the array, period. There's no real other way to express that.
I do understand that. I also understand that String[] is different to Integer[]; but at no point am I trying to mix these together. If I have a generic type T and a class Foo; the compiler doesn't magically let me assign between them. It considers them distinct (in fact, most of the static typing occurs at either compile time, before erasure, or at runtime, well after any of this). "It needs the type to make the array, period" doesn't answer why it needs that type. What is it used for? To stop me assigning an int into a string array? Is that what you're trying to say, or something more?
To put it another way; if I have T[] things = ..., after erasure that will look like Object[] things = .... Are you trying to say that the erasure is to stop me from doing something like (let T = Foo), things[i] = new String()?
I'm saying that Object[] is not the same as String[] or Integer[]. You can't make either of the latter if the type is erased. Which would you make? List<T> what type is T, and which array do I make?
|
0

Why not:

Object [] a = new Object[100];

What does a not do that you would expect a hypothetical "generic" array to do? Each element can be a different type of object. You will have to qualify all accesses to the elements but each element can be anything including null.

In this example the symbol a refers to an object which is of fixed size, and operates an array. The only thing that goes "in" the array are references to other objects.

1 Comment

I understand this; that's not what I'm asking. Please see the update I've made to my question; hopefully that clarifies it.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.