2011-02-10 54 views
11

我正在執行我自己的JVM實現,並且遇到了checkcast指令。完整的文檔是on this page。我很好奇,因爲在枚舉轉換規則時,檢查一個條件是如果被檢查的對象引用是接口類型的。根據我的理解,這不應該是可能的;接口不能直接實例化,任何實現接口的對象都有其他具體的類類型。我錯過了什麼嗎?檢查字節碼指令混亂?

回答

20

看來你不是唯一一個感到困惑的這個定義,這個博客帖子有一個解釋:http://mbravenboer.blogspot.com/2008/12/why-jvm-spec-defines-checkcast-for.html

事實證明,這的確是一個'不可能」的情況。之所以這樣產品可在 說明書中,是因爲checkcast爲陣列遞歸地定義:

  • 如果S是表示將陣列型SC類[],也就是說,類型SC的部件的陣列,然後:
  • ...
  • 如果T是一個數組類型TC [],也就是說,類型TC的組件的陣列,然後的必須滿足以下條件之一:
    • ...
    • TC和SC是參考類型,SC類型可以是b通過遞歸應用這些規則投向TC。

所以,如果你有[]被強制轉換爲收藏[],然後在規則checkcast得到遞歸調用的類型S =列表和T =集合類型列表的對象。注意List是一個接口,但是一個對象在運行時可以有List []類型。如果尚未通過JVM Spec維護人員進行驗證,但據我所知,這是接口類型規則存在的唯一原因。

+0

非常感謝!這正是我正在尋找的那種答案。 – templatetypedef 2011-02-10 22:45:49

-2

如果S是一個接口類型,那麼:

如果T是一個類類型,那麼T必須是對象(§2.4.7)。
如果T是接口類型,那麼T必須與S的接口或S的超接口相同(§2.13.2)。

對我來說這似乎很清楚:一個接口可以轉換爲它擴展的接口。例如,當您在DataInputStream上調用序列化時,會使用這種情況:接口DataInputStream實現Serializable,因此我們無需知道對象的實現類是什麼,就可以將對象轉換爲Serializable。

+1

我想你不明白這個問題。另外,[java.io.DataInputStream](https://docs.oracle.com/javase/8/docs/api/java/io/DataInputStream.html)是一個類,而不是接口。 – 2016-12-17 22:03:34