2017-01-08 16 views
0

假設你有對象ArrayList<Object> arr = new ArrayList<Object>();的ArrayList,然後填寫此ArrayList有幾個不同的對象,它們都來自object繼承。動態(運行時)多態性如何在java中工作?換句話說,JVM如何知道要調用哪些方法?

arr.add(new Integer(1)); 
arr.add("Im a String"); 
arr.add(new SomeOtherObject); 

說你然後遍歷數組列表調用.toString()方法,這實際上會如預期,稱StringInteger類的重載toString()方法,是什麼讓我困惑的是,在JVM中,IntegerString arrayList中的對象被隱式地轉換爲對象,那麼JVM知道如何在它們被放入arrayList之前將它們變回原來的狀態?很抱歉,如果這個問題有一個顯而易見的答案,但是這似乎沒有多大意義的,我

+0

鑄造是不是除了基本類型的情況中的轉換。 – EJP

回答

4

每個對象都有它的類型存儲在該對象的標題。當您將引用轉換爲對象時,這不會以任何方式更改對象。

當你調用.toString例如,它查找從班描述調用該方法。注意:如果可以優化代碼,則不必每次都這樣做。

1

假設你有一個Fooclass,並且你有一個叫arrArrayList<Object>。當你說arr.add(new Foo())Fooclass一個新的對象添加到arr作爲新元素。這是可能的,因爲Fooclass並且從Object繼承。但是,該對象是Foo,即使FooObject繼承。因此,當您撥打toString時,它會調用您創建的Foo對象的toString

讓我們假設你有一個數組列表Bird s和Eagle s fly精美。因此,如果您撥打Birdfly()方法(實際上是Eagle),它會飛得很漂亮。這實際上是繼承的一個重要特徵,它非常有意義。

1

事實是,JVM不知道如何將它們轉換回原來的。我們將不得不爲此完成任務。考慮這個...

SomeOtherObject obj = arr.get(2); //trying to access the third element 

你一定會得到編譯時錯誤(你的代碼行之後)。好吧,現在嘗試顯式轉換返回的對象。

SomeOtherObject obj = (SomeOtherObject)arr.get(2); 

它工作得很好!爲什麼?因爲get()方法返回的對象與它正在播放的類型兼容。

現在考慮這個還(我知道我不能這樣做),只是爲了檢查,如果JVM能告訴我們哪些對象是什麼。

SomeOtherObject obj = (SomeOtherObject)arr.get(1); //1 instead of 2 

是的我知道這個數組的第二個成員是一個字符串,我不能這樣做。但讓我們看看JVM有什麼要說的(雖然沒有編譯器錯誤)。我們得到的消息是該對象不能轉換爲指定的類型。 (但我們沒有得到對象的確切類型)。

你明白了嗎?這裏的JVM只知道傳遞給這個數組的對象只是與Object兼容的對象。它不知道我們是否真的傳遞了String,int(或者整數,因爲原語不能存儲在集合中),或SomeOtherObject(Java中定義的任何類是Object的直接子類)。

現在回答你的問題:

  1. (我怎麼能得到String和整數恢復正常(雖然我仍然要類型轉換它們))的原因是字符串和包裝類(Integer是一個包裝類)重寫了從Object繼承的toString()方法。所以打印這些對象會給出實際的價值。 (JVM如何知道將其轉換爲哪種類型)在返回給用戶之前,JVM實際上不知道哪個對象將被轉換爲哪種類型。它只會返回Object的一個實例(這就是JVM所知道的對象)。我們必須明確地將其轉換爲適當的類型。

希望我回答了你的問題。如果不清楚,請告訴我。

有關運行時多態性(你的標題問題)詳細說明在這個網站給出:http://www.javatpoint.com/runtime-polymorphism-in-java

相關問題