转载自:http://hongjiang.info/scala-pitfalls-11-type-erasure/
scala中用isInstanceOf判断一个对象实例是否是某种类型时,如果类型包含参数类型,会被擦除(jvm的做法)。所以会导致例如下面的问题:
scala中用isInstanceOf判断一个对象实例是否是某种类型时,如果类型包含参数类型,会被擦除(jvm的做法)。所以会导致例如下面的问题:
scala> (1,2).isInstanceOf[Tuple2[String,String]]
<console>:14: warning: fruitless type test: a value of type (Int, Int) cannot also be a (String, String) (but still might match its erasure)
(1,2).isInstanceOf[Tuple2[String,String]]
^
res11: Boolean = true
在给出了一段警告之后,结果返回true,如果数据对象支持模式匹配且元素较少,可以用模式匹配来精确判断:scala> (1,2) match{ case(_:Int, _:Int) => println("ok"); case _ => "no"}
ok
res12: Any = ()
但元素比较多的话,或数据不支持模式匹配,要判断参数类型,就需要让编译器在运行时保持参数类型的信息了,在scala里是通过TypeTag来实现的,TypeTag知识点参考http://hongjiang.info/scala-type-system-manifest-vs-typetag/。如下方式可以作类型检查:scala> def checkType[A: TypeTag](a: A, t: Type) = typeOf[A] <:< t
checkType: [A](a: A, t: reflect.runtime.universe.Type)(implicit evidence$1: reflect.runtime.universe.TypeTag[A])Boolean
scala> checkType((1,2), typeOf[Tuple2[String,String]])
res13: Boolean = false
scala> checkType((1,2), typeOf[Tuple2[Int,Int]])
res14: Boolean = true