11
votes

Pourquoi l'invoquiste Java doit-il résoudre la classe de compilation de la méthode appelée?

Considérez cette classe Java simple:

invokevirtual i


1 commentaires

Cela est dû à la vérification. Voir ma réponse mise à jour ci-dessous.


5 Réponses :


1
votes

Ce n'est pas la façon dont je comprends bien après avoir lu la documentation. Je pense que vous avez des étapes 2 et 3 transposées, ce qui rendrait toute la série d'événements plus logiques.


2 commentaires

Supposons que j'ai des étapes 2 et 3 transposées. (C'est plausible. Dans les docs que j'ai mentionné, la phrase ", la méthode nommée est résolue" semble ambiguë.) Êtes-vous toujours d'accord pour dire que le JVM fait une sorte de chèques contre le type de compilée, ou si vous soupçonnez-vous? J'ai ça tort aussi? (En particulier, tous les chèques contre le type de temps d'exécution?) Je suis toujours assez confiant que la JVM sait que MyClass est le type de temps de compilation associé à l'appel à FOO, même si je suis floue sur ce qu'il fait avec cette information.


Lors de la lecture ultérieure :) 1) L'indice calculé à partir des opérandes d'InvokeVirtual est utilisé pour examiner le pool de myclass constant d'exécution de MyClass, qui indiquera une référence symbolique à la méthode. Quelque chose comme: myclass / foo () v. 2) À partir de cette référence symbolique, la classe "myClass" est levée et la méthode "Void Foo ()" est levée dans cette classe et vérifiait la protection de l'accès. 3) Le type d'exécution de variable "C" est vérifié pour une méthode "Void FOO ()", sinon il recouvre la hiérarchie de la classe jusqu'à ce qu'elle en trouve un. Peut-être que c'est la première étape afin qu'elle puisse échouer rapidement. Michael E pourrait avoir raison;)



1
votes

Vraisemblablement, les # 1 et n ° 2 sont déjà arrivés par le compilateur. Je soupçonne qu'au moins une partie de l'objectif est de s'assurer que les chiffres sont toujours tenus avec la version de la classe dans l'environnement d'exécution, qui peut être différente de la version, le code a été compilé.

Je n'ai pas digéré la documentation InvokeVirtual pour vérifier votre résumé, alors Rob Heiser pourrait avoir raison.


0 commentaires

1
votes

Je suppose que la réponse "B".

Les chèques de liaison ou de modificateur d'accès effectués dans les n ° 1 et n ° 2 sont essentiels pour éviter que certaines mauvaises choses ne se produisent et que ces chèques doivent être effectuées en fonction du type de temps de compilation, plutôt que de la hiérarchie de type d'exécution. (S'il vous plaît expliquer.)

# 1 est décrit par 5.4. 3.3 Résolution de la méthode , qui fait des contrôles importants. Par exemple, # 1 vérifie l'accessibilité de la méthode dans le type de compilation et peut renvoyer une pièce illeAccessError si elle n'est pas la suivante:

... sinon, si la méthode référencée n'est pas accessible (§5.4.4) à D, la résolution de la méthode jette un système illégalAccessError. ...

Si vous avez vérifié uniquement le type d'exécution (via n ° 3), le type d'exécution pourrait alors élargir illégalement l'accessibilité de la méthode remplacée (A.K.A. une "mauvaise chose"). Son vrai que le compilateur devrait empêcher un tel cas, mais la JVM se protège néanmoins du code Rogue (par ex. Code malveillant construit manuellement).


0 commentaires

4
votes

Il s'agit de la performance. Lorsque, en déterminant le type de compilation (AKA: type statique), la JVM peut calculer l'index du procédé invoqué dans la table de fonction virtuelle du type d'exécution (AKA: type dynamique). L'utilisation de cet index étape 3 devient simplement un accès dans un tableau pouvant être accompli en temps constant. Aucune boucle n'est nécessaire.

Exemple: p> xxx pré>

par défaut, A code> étend objet code> qui définit ces méthodes ( Les méthodes finales omis telles qu'elles sont appelées via invokespecial code>): p> xxx pré>

maintenant, considérez cette invocation: p>

A x = ...;
x.foo();


1 commentaires

Une petite correction est que les méthodes final sont invoquées avec invokevirtual .



0
votes

Pour comprendre totalement ce genre de choses, vous devez comprendre comment fonctionne la résolution de la méthode en Java. Si vous recherchez une explication approfondie, je suggère de regarder le livre "à l'intérieur de la machine virtuelle Java". Les sections suivantes du chapitre 8, "Le modèle de liaison" sont disponibles en ligne et semblent particulièrement pertinentes:


0 commentaires