classOf[T]
获取类型T的Class对象。
classOf方法定义在scala.Predef object:
object Predef extends LowPriorityImplicits {
/** Return the runtime representation of a class type. This is a stub method.
* The actual implementation is filled in by the compiler.
*/
def classOf[T]: Class[T] = null
...
}
classOf的注释翻译过来的意思是:返回在运行过程中的类型。这是一个存根方法。具体的实现是由编译器填补(自动生成)。
Predef object是默认导入的,所以classOf方法相当于一个全局方法。
isInstanceOf[T]
判断对象是否为T类型的实例。
isInstanceOf和asInstanceOf由scala.Any类定义,所以所有对象都自动拥有isInstanceOf和asInstanceOf这两个方法。
再看一下例子:
scala> 1.isInstanceOf[String]
res0: false
scala> List(1).isInstanceOf[List[String]]
res0: true
由于Scala像Java一样泛型存在类型擦除的原因,List(1).isInstanceOf[List[String]]及相当于List(1).isInstanceOf[List[_]], List(1)是List的实例。这样的问题在模式匹配的时候也会遇到,关于如何克服类似的问题,可以参见scala中的类型擦除的问题
asInstanceOf[T]
将对象类型强制转换为T类型。
还是由于泛型存在类型擦除的原因,1.asInstanceOf[String]在运行时会抛出ClassCastException异常,而List(1).asInstanceOf[List[String]]将不会。
在scala 讨论组里有人问道这样一个问题:
“I expect “new AnyRef().isInstanceOf[AnyVal]” to be false, but I get true instead”
scala> new AnyRef().isInstanceOf[AnyVal]
res0: Boolean = true
大家有兴趣看以看看后面的解答,不过试了scala 2.9,这种用法已经被编译器禁止了:
scala> new AnyRef().isInstanceOf[AnyVal]
<console>:8: error: type AnyVal cannot be used in a type pattern or isInstanceOf test
new AnyRef().isInstanceOf[AnyVal]
还有,值得提一下的一个小细节就是,通过观察编译输出的AST, 知道对于在基本类型如Int等的对象上调用asInstanceOf[T], Scala会将其转换为调用相应的toT方法, 如 97.asInstanceOf[Char], 就会转换为97.toChar, 其中toChar定义在scala.Int:
final class Int extends AnyVal {
...
def toChar: Char = sys.error("stub")
...
}
而后, Scala编译器会进一步将其编译成与“(char)97”相同的字节码。
结论: 总而言之,我们把classOf[T]看成Java里的T.class, obj.isInstanceOf[T]看成 obj instanceof T, obj.asInstanceOf[T]看成(T)obj就对了。
但是同样也要注意类型擦除造成的问题。
参考:https://blog.csdn.net/u013007900/article/details/79226806