我试图回答这个问题,因为我认为我知道答案.事实证明,我不太了解:/
这是我做过的测试:
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
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?为什么只有第二次as投掷,而不是第一次?
0__*_*0__ 10
这是因为只有在使用值执行某些操作时才会抛出class-cast-exception,在执行后调用它上面的方法.例如,在REPL中,您将toString在第二种情况下进行呼叫.注意:
new Inst[String].as(3); () // nothing happens
new Inst[String].as(3).toString; () // exception
Run Code Online (Sandbox Code Playgroud)
这需要额外步骤的原因是在运行时擦除的Inst[T]类型参数是通用的T; 只有当调用站点(具有静态类型知识T)尝试在结果上调用方法时,才会进行实际的类型检查.
对于你的后续问题,toString是在任何对象上定义的,因为它T是通用的,你有一个盒装整数(<: AnyRef),toString并且println在is方法中成功.所以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!
Run Code Online (Sandbox Code Playgroud)