How does `isInstanceOf` work?
Domanda
Assume, we have:
class B
class A extends B
trait T
Then it holds:
val a: A with T = new A with T
a.isInstanceOf[B] // result is true !
Is it right to say, the isInstanceOf
method checks, if there is at least one type (not all types) which matches the right hand side in a subtype relationship?
At first look, I thought a value with type A with T
can not be a subtype of B
, because A
and T
are not both subtypes of B
. But it is A
or T
is a subtype of B
-- is that right ?
Soluzione
isInstanceOf
looks if there is a corresponding entry in the inheritance chain. The chain of A with T
includes A
, B
and T
, so a.isInstanceOf[B]
must be true.
edit:
Actually the generated byte code calls javas instanceof
, so it would be a instanceof B
in java. A little more complex call like a.isInstanceOf[A with T]
would be (a instanceof A) && (a instanceof T)
.
Altri suggerimenti
At first look, I thought a value with type A with T can not be a subtype of B
There's are two misconceptions here. First, that the static type of an instance has any bearing on the result of isInstanceOf
: there is none. To be clear, when doing a.isInstanceOf[B]
, the fact that a
is of type A with T
is not relevant.
The method isInstanceOf
is implemented at the bytecode level by the JVM. It looks at the class information every instance carries, and checks whether B
one of the classes (the class of the instance itself and its ancestors), or one of the implemented interfaces. That's the "is-a" relationship: "a is a B".
Technically, isInstanceOf
is part of Java's reflection, where it is known as instanceof
.
The second misconception is the inheritance can somehow remove a parent type. That never happens: inheritance only adds types, never removes them. The type A with T
is an A
, a B
, a T
, an AnyVal
and an Any
. So even if isInstanceOf
did look at the type A with T
, it would still return true.