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