web-dev-qa-db-fra.com

Comment fonctionne `isInstanceOf`?

Supposons que nous ayons:

class B
class A extends B
trait T

Ensuite, il détient:

val a: A with T = new A with T 
a.isInstanceOf[B]  // result is true !

Est-il juste de dire que la méthode isInstanceOf vérifie s'il existe au moins un type (pas tous les types) qui correspond au côté droit dans une relation de sous-type?

À première vue, j'ai pensé à une valeur de type A with T ne peut pas être un sous-type de B, car AetT ne sont pas les deux sous-types de B. Mais c'est AoT est un sous-type de B - est-ce vrai?

23
John Threepwood

isInstanceOf recherche s'il existe une entrée correspondante dans la chaîne d'héritage. La chaîne de A with T inclut A, B et T, donc a.isInstanceOf[B] doit être vrai.

éditer:

En fait, le code d'octet généré appelle javas instanceof, donc ce serait a instanceof B en Java. Un appel un peu plus complexe comme a.isInstanceOf[A with T] serait (a instanceof A) && (a instanceof T).

36
drexin

À première vue, je pensais qu'une valeur de type A avec T ne pouvait pas être un sous-type de B

Il y a deux idées fausses ici. Premièrement, que le type statique d'une instance a une incidence sur le résultat de isInstanceOf: il n'y en a pas. Pour être clair, lorsque vous faites a.isInstanceOf[B], le fait que a est de type A with Tn'est pas pertinent.

La méthode isInstanceOf est implémentée au niveau du bytecode par la JVM. Il regarde les informations de classe chaque instance porte, et vérifie si B une des classes (la classe de l'instance elle-même et ses ancêtres), ou l'une des interfaces implémentées. C'est la relation "est-un": "a est un B".

Techniquement, isInstanceOf fait partie de la réflexion de Java, où il est appelé instanceof.

La deuxième idée fausse est que l'héritage peut en quelque sorte supprimer un type parent. Cela n'arrive jamais: l'héritage n'ajoute que des types, ne les supprime jamais. Le type A with T est un A, un B, un T, un AnyVal et un Any. Donc, même si isInstanceOf a bien regardé le type A with T, cela reviendrait toujours vrai.

11
Daniel C. Sobral