数组协方差

对象数组是协变的,这意味着就像 IntegerNumber 的子类一样,Integer[]Number[] 的子类。这可能看起来很直观,但可能导致令人惊讶的行为:

Integer[] integerArray = {1, 2, 3};
Number[] numberArray = integerArray;  // valid
Number firstElement = numberArray[0]; // valid
numberArray[0] = 4L;                  // throws ArrayStoreException at runtime

虽然 Integer[]Number[] 的子类,但它只能保存 Integers,并且尝试分配 Long 元素会抛出运行时异常。

请注意,此行为对于数组是唯一的,可以通过使用通用 List 来避免:

List<Integer> integerList = Arrays.asList(1, 2, 3);
//List<Number> numberList = integerList;  // compile error
List<? extends Number> numberList = integerList;
Number firstElement = numberList.get(0);
//numberList.set(0, 4L);                  // compile error

所有数组元素都不必共享相同的类型,只要它们是数组类型的子类:

interface I {}

class A implements I {}
class B implements I {}
class C implements I {}

I[] array10 = new I[] { new A(), new B(), new C() }; // Create an array with new
                                                     // operator and array initializer.

I[] array11 = { new A(), new B(), new C() };         // Shortcut syntax with array
                                                     // initializer.

I[] array12 = new I[3];                              // { null, null, null }

I[] array13 = new A[] { new A(), new A() };          // Works because A implements I.

Object[] array14 = new Object[] { "Hello, World!", 3.14159, 42 }; // Create an array with
                                                     // new operator and array initializer.

Object[] array15 = { new A(), 64, "My String" };     // Shortcut syntax 
                                                     // with array initializer.