Generally, Java can be considered as a type-safe language. I know that there are some flaws with generics, but I recently came across a Problem I never had before. To break it down:
Object[] objects = new Integer[10];
objects[0] = "Hello World";
will NOT result in a compile-time error as expected. I would assume that the declaration of an Array of Object
will disallow to point to to an array of something else. In Generics I'm not allowed to make such weird things like:
ArrayList<Object> objs = new ArrayList<Integer>
and if I try to kind of trick Java into doing something with
ArrayList<? extends Object> objects = new ArrayList<Integer>
I'm allowed to declare it, but I can only add Objects of type null
.
Why doesn't Java prevent the declaration of such weired arrays?
Firstly, I should point out that this is type-safe.
because an exception will be thrown. (It is not statically type-safe ... but that is a different statement entirely.)
The reason that Java allows this is historical. Until Java 5, Java did not support any form of generics. Gosling has said that if they had had the time to figure out and incorporate generics into Java 1.0, they would have done so.
Unfortunately, they didn't. But they still wanted to be able write things like a general purpose sort method with the following signature:
To make this method work for any kind of object array (without generics), it was necessary to make arrays covariant; i.e. to make it legal to pass a
String[]
orInteger[]
as an argument where the formal type isObject[]
. If they hadn't done that you would have had to copy theString[]
to anObject[]
, sort it, and then copy it back.I don't think there's an answer to this besides "legacy design". (Which I admit is a fancy way of saying "because".) You pretty much need to be able to do an equivalent of the last assignment you show somehow. (Otherwise you're stuck to making lots and lots of copies with manual up/down casts, assuming language features of Java pre 1.4)
In Java 1 when type semantics for arrays were basically set in stone, generics weren't available, or even up for consideration for a long while yet. So there was no mechanism available to express the higher-order type constraints needed to make this construct type-safe – and Gosling (IIRC a fan of simplicity) felt resolving this edge case of compile-time type safety wasn't worth complicated the language with whichever solutions were available. Or wasn't bothered by doing the check at runtime enough to even look for a solution. (At the end of the day language design decisions are arbitrary to at least some degree, and there's only one person that could answer this with any certainty.)
"Because it has to".
To elaborate a bit, consider the following example:
Now, how would the Java compiler know which assignments to allow and which to refuse? It can't. The compile-time type is Object so the compiler will let you put any Object in your array, simply because it doesn't have any knowledge of the runtime type of your array.
actually in case of arrays you get a exception at run time called ArrayStoreException when you add wrong type of element In this case a String. In case of generics there is no such exception. its for the
very same reason
you are not allowed to add anything but object, as you might just add a wrong type into the list.There's Discussion that I found while I google it
I Found: