Question Confusion sur l'instruction bytecode de vérification?


Je travaille sur ma propre implémentation de la JVM et je suis venu à la checkcast instruction. La documentation complète est sur cette page. Je suis curieux, car lors de l'énumération des règles de fonctionnement de la distribution, une condition est vérifiée si la référence de l'objet à vérifier est de type interface. Par ma compréhension, cela ne devrait pas être possible; les interfaces ne peuvent pas être instanciées directement, et tout objet qui implémente une interface a un autre type de classe concret. Est-ce que je manque quelque chose?


11
2018-02-10 22:11


origine


Réponses:


Il semble que vous n'étiez pas le seul à être confus par cette définition, cet article de blog a une explication: http://mbravenboer.blogspot.com/2008/12/why-jvm-spec-defines-checkcast-for.html

Il s’agit bien d’un cas «impossible». La raison pour laquelle cet article est dans le   spécification, est parce que la vérification est définie récursivement pour les tableaux:

  • Si S est une classe représentant le type de tableau SC [], c'est-à-dire un tableau de composants de type SC, alors:
  • ...
  • Si T est un type de tableau TC [], c'est-à-dire un tableau de composants de type TC, l'un des éléments suivants doit être vrai:      
    • ...
    • TC et SC sont des types de référence, et le type SC peut être converti en TC par application récursive de ces règles.

Ainsi, si vous avez un objet de type List [] qui est converti en une collection [], les règles de vérification sont invoquées de manière récursive pour les types S = List et T = Collection. Notez que List est une interface, mais qu'un objet peut avoir le type List [] au moment de l'exécution. Si cela n'a pas été vérifié avec les responsables de JVM Spec, mais pour autant que je sache, c'est la seule raison pour laquelle la règle pour les types d'interface existe.


20
2018-02-10 22:37



Si S est un type d'interface, alors:

Si T est un type de classe, alors T doit être Object (§2.4.7).
  Si T est un type d'interface, alors T doit être la même interface que S ou une superinterface de S (§ 2.13.2).

Cela me semble clair: une interface peut être convertie en une interface étendue. Ce cas est utilisé par exemple lorsque vous appelez la sérialisation sur DataInputStream: l'interface DataInputStream implémente Serializable, nous avons donc converti l'objet en Serializable sans même savoir quelle est la classe implémentée de l'objet.


-2
2018-02-10 22:24