1

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

  • At compile time(and also at runtime) array variable in above example has type A[]
  • Compiler's duty is to make sure that only A[] or some subtype of A[] is assigned to array variable.
  • Same goes with components of array (array[0]), compiler will only check if the value being assigned is A or some subtype of A.

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 ?

mightyWOZ
  • 7,946
  • 3
  • 29
  • 46
  • Possible duplicate of [Why are arrays covariant but generics are invariant?](https://stackoverflow.com/questions/18666710/why-are-arrays-covariant-but-generics-are-invariant) – takendarkk Mar 01 '19 at 17:15
  • @takendarkk i dont think so, i am not asking about covariant arrays. even if arrays are covariant type checking can be done at compile time. – mightyWOZ Mar 01 '19 at 17:18
  • @takendarkk if you think that post have any answer to my question please point me where it says anything about time of type checking ? – mightyWOZ Mar 01 '19 at 17:27
  • see. https://stackoverflow.com/questions/13685158/why-does-java-allow-type-unsafe-array-assignments. – togise Mar 01 '19 at 17:28
  • @pacman thanks, but i am not asking why covariant arrays are allowed, I am asking why type checking is delayed. instead of throwing an exception at runtime why cant compiler throw an error. – mightyWOZ Mar 01 '19 at 17:33

2 Answers2

1

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.

daniu
  • 14,137
  • 4
  • 32
  • 53
1

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();
Daniele
  • 2,672
  • 1
  • 14
  • 20