Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why instance of superclass can be put into array of subclass?

Let's assume we have 2 classes:

class X { }

class Y extends X { }

Create an array in main function:

Y[] yArr = new Y[3] // created Y's class objects array

X[] xArr = yArr;

xArr[0]= new X() // VALID. WHY?

How can it be?? Because xArr refers to Y[] object and for my understanding it cannot create an X object.

like image 804
Ernusc Avatar asked Oct 28 '13 19:10

Ernusc


1 Answers

The Java compiler allows this because in Java arrays are covariant. I.e., one can say:

Superclass[] arr = new Subclass[3];

This allows code such as your xArr[0]= new X(); to compile. However, the JVM will catch this error at runtime and throw an ArrayStoreException. It knows at runtime that it's really a Y[3] and thus can't store an X.

The JLS, Section 4.10.3, establishes the covariance of array types:

The following rules define the direct supertype relation among array types:

  • If S and T are both reference types, then S[] >1 T[] iff S >1 T.

  • Object >1 Object[]

  • Cloneable >1 Object[]

  • java.io.Serializable >1 Object[]

  • If P is a primitive type, then:

    • Object >1 P[]

    • Cloneable >1 P[]

    • java.io.Serializable >1 P[]

This is in contrast to generics, which not covariant -- they are invariant. I.e.

ArrayList<Superclass> list = new ArrayList<Subclass>();  // doesn't compile.
like image 109
rgettman Avatar answered Nov 01 '22 07:11

rgettman