2011-02-10 8 views
11

Estoy trabajando en mi propia implementación de la JVM y llegué a la instrucción checkcast. La documentación completa es on this page. Tengo curiosidad porque al enumerar las reglas sobre cómo funciona el elenco, una condición que se verifica es si la referencia del objeto que se está verificando es del tipo de interfaz. Según entiendo, esto no debería ser posible; las interfaces no se pueden instanciar directamente, y cualquier objeto que implemente una interfaz tiene algún otro tipo de clase concreto. ¿Me estoy perdiendo de algo?Confusión en la instrucción de código de bytes de cheque?

Respuesta

20

Parece que no era el único confundido acerca de esta definición, esta entrada del blog tiene una explicación: http://mbravenboer.blogspot.com/2008/12/why-jvm-spec-defines-checkcast-for.html

Resulta que esto es de hecho un caso imposible ''. La razón por este producto está en la especificación , es porque checkcast se define de forma recursiva para matrices:

  • Si S es una clase que representa el tipo de matriz SC [], es decir, una matriz de componentes de tipo SC, entonces:
  • ...
  • Si T es un tipo de matriz TC [], es decir, un conjunto de componentes de tipo TC, y después uno de lo siguiente debe ser verdadera:
    • ...
    • TC y SC son tipos de referencia, y el tipo SC puede b echado a TC mediante la aplicación recursiva de estas reglas.

Por lo tanto, si usted tiene un objeto de tipo List [] que se convierte en una colección [], entonces las reglas para obtener de forma recursiva checkcast invocados por los tipos S = Lista y T = Colección. Observe que List es una interfaz, pero un objeto puede tener un tipo List [] en tiempo de ejecución. Si no he verificado esto con los mantenedores de las especificaciones de JVM, pero hasta donde puedo ver, esta es la única razón por la cual la regla para los tipos de interfaz está ahí.

+0

¡Muchas gracias! Ese es exactamente el tipo de respuesta que estaba buscando. – templatetypedef

+0

+1 Brillante. :) – biziclop

-2

Si S es un tipo de interfaz, entonces:

Si T es un tipo de clase, entonces T debe ser objeto (§2.4.7).
Si T es un tipo de interfaz, entonces T debe ser la misma interfaz que S o una superinterfaz de S (§2.13.2).

Eso me parece claro: se puede convertir una interfaz en una interfaz que se amplía. Este caso se usa, por ejemplo, cuando llamas a serialización en DataInputStream: la interfaz DataInputStream implementa Serializable, por lo que convertimos el objeto a Serializable sin siquiera saber cuál es la clase implementada del objeto.

+1

Creo que no entendiste la pregunta. Además, [java.io.DataInputStream] (https://docs.oracle.com/javase/8/docs/api/java/io/DataInputStream.html) es una clase, no una interfaz. –

Cuestiones relacionadas