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)
.