如何使用反射检查给定类型是某个对象?

How to check a given Type is a certain object using reflection?

假设有代码

sealed trait SomeTrait
case class SomeClass() extends SomeTrait
case object SomeObject extends SomeTrait

然后通过反射得到someTraitType: Type

要检查 someTraitTypeSomeClass 的类型,可以轻松完成 someTraitType =:= typeOf[SomeClass]

问题是如何检查someTraitTypeSomeObject

还有一个问题,SomeObject实例是否可以从对应的Type中得到,所以可以执行一个简单的==

使用 scala.reflect.runtime.universe._ 中的 TypeTag 来检查类型是否相等时需要小心。

考虑以下检查

def isSomeClass[T <: SomeTrait: TypeTag](t: T) = {
  typeOf[T] =:= typeOf[SomeClass]
}

def isSomeObject[T <: SomeTrait: TypeTag](t: T) = {
  typeOf[T] =:= typeOf[SomeObject.type]
}

以上方法似乎适用于以下设置

val s1 = SomeClass()
val s2 = SomeObject

println(isSomeClass(s1)) //prints true
println(isSomeObject(s2)) //prints true

然而,当编译器“忘记”s1s2 的类型时,检查失败。

val s1: SomeTrait = SomeClass()
val s2: SomeTrait = SomeObject

println(isSomeClass(s1)) //prints false
println(isSomeObject(s2)) //prints false

更好的方法是使用适用于这两种情况的 s1.isInstanceOf[SomeClass]s2.isInstanceOf[SomeObject.type]