Reputation: 8345
I am reading Item 28 of Effective java, in which author writes
The second major difference between arrays and generics is that arrays are reified [JLS, 4.7]. This means that arrays know and enforce their element type at runtime.
but why at runtime ? For example, consider two classes where A is the parent of B
public static void main(String[] args) {
A[] array = new B[10];
array[0] = new A();
}
This code throws an ArrayStoreException. To me, it seems that error could have been identified by the compiler. So why did the compiler let it pass. Is it because JLS doesn't want the compiler to be that smart (slow)?.
JLS 10.5 For an array whose type is A[], where A is a reference type, an assignment to a component of the array is checked at run time to ensure that the value being assigned is assignable to the component.
Now my understanding is that
Why doesn't the compiler take into account the actual array object (B[10]) when A() is assigned to array[0]. is it because the compiler doesn't have that information available to it ?
Upvotes: 1
Views: 119
Reputation: 2837
To me, it seems that error could have been identified by the compiler.
well no; the compiler can't determine what the actual type of array
will be at runtime.
Let's make a trivial example,
array = myRandomFunction()>0 ? new A[10] : new B[10];
then the actual type of array
can be either A[]
or B[]
, and the compiler can't help.
If you think about it; this is similar to what happens for NullPointerException
: the compiler doesn't complain about the following (even though if will always throw at runtime)
Object a=null;
a.toString();
Upvotes: 1
Reputation: 15008
The error can be detected by the compiler in the code you post, but not in the general case.
Because of covariance, the B[]
can be assigned to the A[]
variable in the first line. If you pass that array to a method that does the assignment in your second line, the compiler is not able to detect the original type of the array.
Hence, both lines are valid at compile time.
Upvotes: 1