31

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 ?

John Threepwood
  • 15,593
  • 27
  • 93
  • 149
  • Here a quick overview of object equality http://joelabrahamsson.com/learning-scala-part-eight-scalas-type-hierarchy-and-object-equality/ – Jaider Apr 17 '13 at 03:59

2 Answers2

41

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

drexin
  • 24,225
  • 4
  • 67
  • 81
  • 1
    Thank you for the background information, that helped a lot. Do you know where I can find more background information about the Scala's `isInstanceOf` method ? The Scala API does not tell much about it. – John Threepwood Jul 02 '12 at 10:19
  • There's not much to tell. It is just `instanceof`. – drexin Jul 02 '12 at 11:20
13

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.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • Do you know how i can prove `Null` and `Nothing` are sub-types of all things in the REPL? `"A".isInstanceOf[Null]` errors? as does `Nothing`? I guess that makes sense; ie `"A" instanceof null` wouldn't work in Java. Do I just have to take the docs word for it?! – Toby Jul 01 '14 at 19:13
  • @Toby `Nothing` does not exist in Java, since it treats classes and primitives and distinct things, and `instanceof` only pertains to the former. Also, `Null` does not exist either in Java, which has no concept of a "bottom". – Daniel C. Sobral Jul 02 '14 at 03:42