scala中的classOf、isInstanceOf、asInstanceOf

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值