How do I know if two objects of inner class have the same runtime type? In the example below I expect to see the class of aa.getClass == a.Inner and ba.getClass == b.Inner, but in fact they are both Outer.Inner and equal.
class Outer{
class Inner{}
}
val a = new Outer
val b = new Outer
val aa = new a.Inner
val ab = new a.Inner
val ba = new b.Inner
val res1 = aa.getClass == ba.getClass
val res2 = aa.isInstanceOf[ab.type ]
scala> | | defined class Outer
scala> a: Outer = Outer@550a1967
scala> b: Outer = Outer@5f9678e1
scala> aa: a.Inner = Outer$Inner@70a36a66
scala> ab: a.Inner = Outer$Inner@1dd6d4b7
scala> ba: b.Inner = Outer$Inner@2e61d218
scala> res1: Boolean = true
scala> res2: Boolean = false
... aa.getClass == a.Inner and ba.getClass == b.Inner, but in fact they are both Outer.Inner and equal
This is not true. Inner is a class member and is unique to its parent instance of Outer. This means that both a and b have their own unique version of Inner, which are incompatible types. So a.Inner is not the same type as b.Inner, and therefore an a.Inner can never be equal to a b.Inner. I cannot assign one for the other:
scala> val z: a.Inner = aa // aa is a.Inner, so this is ok
z: a.Inner = Outer$Inner@575d06dd
scala> val z: b.Inner = aa // aa is not b.Inner, so it fails to compile
<console>:14: error: type mismatch;
found : a.Inner
required: b.Inner
val z: b.Inner = aa
^
getClass just isn't very useful here.
We can prove this with reflection:
import scala.reflect.runtime.universe._
def tpeOf[A](a: A)(implicit tt: TypeTag[A]) = tt.tpe
scala> tpeOf(aa) =:= tpeOf(ba) // different Outer parents
res24: Boolean = false
scala> tpeOf(aa) =:= tpeOf(aa) // Same instance
res25: Boolean = true
scala> tpeOf(aa) =:= tpeOf(ab) // Same Outer parent
res26: Boolean = true
On the other hand, you can use Outer#Inner to specify that you don't care which Outer your Inner type belongs to.
val x: Outer#Inner = aa
val x: Outer#Inner = ab
val x: Outer#Inner = ba
So as stated by @BenReich, you could use aa.isInstanceOf[Outer#Inner] to check if you have any of those types, and they would all return true.
ab.type means something completely different. ab.type is a singleton type that contains nothing but ab. So naturally then, aa.isInstanceOf[ab.type] must be false, because aa is not ab, regardless of whether or not they are both a.Inner.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With