scala - implicitly - ¿Cómo funciona `isInstanceOf`?
scala self class (2)
Supongamos que tenemos:
class B
class A extends B
trait T
Entonces se sostiene:
val a: A with T = new A with T
a.isInstanceOf[B] // result is true !
¿Es correcto decir que el método isInstanceOf comprueba si hay al menos un tipo (no todos los tipos) que coincida con el lado derecho en una relación de subtipo?
A primera vista, pensé que un valor con el tipo A with T no puede ser un subtipo de B , porque A y T no son ambos subtipos de B Pero si A o T es un subtipo de B , ¿es así?
A primera vista, pensé que un valor con el tipo A con T no puede ser un subtipo de B
Hay dos conceptos erróneos aquí. Primero, que el tipo estático de una instancia tiene alguna relación con el resultado de isInstanceOf : no hay ninguno. Para ser claros, cuando se hace a.isInstanceOf[B] , el hecho de que a sea de tipo A with T no es relevante .
El método isInstanceOf se implementa en el nivel de bytecode por la JVM. Examina la información de clase que lleva cada instancia y verifica si B una de las clases (la clase de la instancia en sí misma y sus ancestros) o una de las interfaces implementadas. Esa es la relación "is-a": "a es a B".
Técnicamente, isInstanceOf es parte de la reflexión de Java, donde se conoce como instanceof .
El segundo error es que la herencia puede, de alguna manera, eliminar un tipo primario. Eso nunca sucede: la herencia solo agrega tipos, nunca los elimina. El tipo A with T es una A , una B , una T , una AnyVal y una Any . Por lo tanto, incluso si isInstanceOf miró el tipo A with T , seguiría siendo verdadero.
isInstanceOf busca si hay una entrada correspondiente en la cadena de herencia. La cadena de A with T incluye A , B y T , por lo que a.isInstanceOf[B] debe ser verdadera.
editar:
En realidad, el código de byte generado llama javas instanceof , por lo que sería a instanceof B en java. Una llamada un poco más compleja como a.isInstanceOf[A with T] sería (a instanceof A) && (a instanceof T) .