我们假设我们有两个类:
class X { }
class Y extends X { }
Run Code Online (Sandbox Code Playgroud)
在main函数中创建一个数组:
Y[] yArr = new Y[3] // created Y's class objects array
X[] xArr = yArr;
xArr[0]= new X() // VALID. WHY?
Run Code Online (Sandbox Code Playgroud)
怎么会这样??因为xArr引用Y[]对象并且为了我的理解它不能创建X对象.
Java编译器允许这样做,因为在Java数组中是协变的.即,可以说:
Superclass[] arr = new Subclass[3];
Run Code Online (Sandbox Code Playgroud)
这允许你的代码xArr[0]= new X();编译.但是,JVM将在运行时捕获此错误并抛出ArrayStoreException.它在运行时知道它确实是一个Y[3],因此无法存储X.
的JLS,4.10.3节,规定阵列类型的协方差:
以下规则定义了数组类型之间的直接超类型关系:
如果S和T都是引用类型,则S []> 1 T [] iff S> 1 T.
对象> 1对象[]
Cloneable> 1 Object []
java.io.Serializable> 1对象[]
如果P是基本类型,则:
对象> 1 P []
可克隆> 1 P []
java.io.Serializable> 1 P []
这与仿制药相反,仿制药不是协变的 - 它们是不变的.即
ArrayList<Superclass> list = new ArrayList<Subclass>(); // doesn't compile.
Run Code Online (Sandbox Code Playgroud)