2013-10-28 55 views
6

假設我們有2類:爲什麼超類的實例可以放入子類的數組中?

class X { } 

class Y extends X { } 

創建主要功能的數組:

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

X[] xArr = yArr; 

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

怎麼可能?因爲xArr指的是Y[]對象,並且對於我的理解,它不能創建X對象。

回答

9

Java編譯器允許這樣做,因爲Java中的數組是協變的。即,可以說:

Superclass[] arr = new Subclass[3]; 

這使得代碼如你xArr[0]= new X();編譯。但是,JVM會在運行時捕獲此錯誤並拋出一個ArrayStoreException。它知道在運行時它確實是Y[3],因此不能存儲X

JLS, Section 4.10.3,建立數組類型的協方差:

以下規則定義陣列 類型之間的直接父類型關係:

  • 如果S和T是兩個參考類型,那麼S []> 1 T [] iff S> 1 T.

  • Object> 1 Object []

  • Cloneable的> 1個對象[]

  • 了java.io.Serializable> 1個對象[]

  • 如果P是一個基本類型,那麼:

    • 對象> 1個P [ ]

    • Cloneable的> 1 P []

    • 了java.io.Serializable> 1 P []

這與仿製藥,這不是協變的 - 它們是不變的。即

ArrayList<Superclass> list = new ArrayList<Subclass>(); // doesn't compile. 
+0

清潔和整潔..! –

相關問題