当前位置:  开发笔记 > 编程语言 > 正文

为什么`.asInstanceOf`有时会抛出,有时不抛出?

如何解决《为什么`.asInstanceOf`有时会抛出,有时不抛出?》经验,为你挑选了1个好方法。

我试图回答这个问题,因为我认为我知道答案.事实证明,我不太了解:/

这是我做过的测试:

class Inst[T] { 
  def is(x: Any) = scala.util.Try { as(x) }.isSuccess
  def as(x: Any): T = x.asInstanceOf[T]
}

scala> new Inst[String].is(3)
res17: Boolean = true

scala> new Inst[String].as(3)
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
 ... 33 elided

这里发生了什么?为什么只有第二次as投掷,而不是第一次?



1> 0__..:

这是因为只有在使用值执行某些操作时才会抛出class-cast-exception,在执行后调用它上面的方法.例如,在REPL中,您将toString在第二种情况下进行呼叫.注意:

new Inst[String].as(3); ()           // nothing happens
new Inst[String].as(3).toString; ()  // exception

这需要额外步骤的原因是在运行时擦除的Inst[T]类型参数是通用的T; 只有当调用站点(具有静态类型知识T)尝试在结果上调用方法时,才会进行实际的类型检查.


对于你的后续问题,toString是在任何对象上定义的,因为它T是通用的,你有一个盒装整数(<: AnyRef),toString并且printlnis方法中成功.所以Try失败的另一个例子是:

class Inst[T] { 
  def foo(x: Any)(implicit ev: T <:< String) = scala.util.Try {
    ev(as(x)).reverse
  }.isSuccess
}

new Inst[String].foo(3)  // false!

推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有