2011-02-10 74 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