1. 程式人生 > >學習Java之對物件宣告型別的轉型的一點點感覺

學習Java之對物件宣告型別的轉型的一點點感覺

昨天,我寫程式的時候,編譯時,編譯器報了一個錯誤:Object型別不能賦予String型別變數。

程式如下:

Iterator iterator = myList.iterator();
while(iterator.hasNext()) {
    //String str = itrator.next();//錯誤,沒有強制轉為子型別宣告
    String str = iterator.next();//正確
}

我們知道Iterator的next()方法返回Object型別物件。在這裡,我明顯犯了一個很低階的錯誤——把父型別宣告變數標識的物件沒有強制轉型為子型別宣告來標識。

在我們所有看的書中,都把轉型叫做對物件的轉型,這麼稱呼這個操作過程,很容易讓我誤解是物件的例項的類在JRE中發生了變化,是對像的本質發生了變化,這就是這種稱呼對我造成的誤解和誤導。

但現在就以上面的程式碼,讓我講講書上說的物件的轉型在JVM中發生了什麼變化——這裡要顯示轉型的原因:因為next()返回Object型別的結果,現在要把Object型別的(隱式的)引用變數的值賦予String型別,因為Java是強型別語言,所以就要重新宣告為String型別。那麼,JVM對物件的描述資訊就要與Object型別宣告時不同,由於其heap中的例項(物件)滿足引用變數的宣告型別轉換的條件,因它是用String類模板來建立的物件,即可以從例項的類描述中獲得要轉換到的宣告型別的資訊,因此可以做此物件的宣告型別的轉換。

這個例子中,是由Object轉為String,是從類的上層變為類的下層,是屬於窄化轉換,如圖:

類層次

因Java中型別的窄化轉換使物件的適用性變小,物件的限制就會變多,為了保證程式的精確性,就需要強制轉型。

由此錯誤,讓我對物件型別的轉換有了以上的思索,那就是讓我對以前我一直以為的物件的轉型有了一個更深的認知,是物件的轉型實質是引用宣告變數的轉型,而不是heap中的物件發生了變化,若說變化,那就是對物件的描述資訊由原來宣告的型別變為了被轉型的型別描述,這便是塞翁失馬焉知非福。