陣列協方差

物件陣列是協變的,這意味著就像 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.