Scala:为什么 asInstanceOf 可以接受类型参数而 isInstanceOf 不能? [英] Scala: Why asInstanceOf can accept a type parameter but isInstanceOf can not?

查看:72
本文介绍了Scala:为什么 asInstanceOf 可以接受类型参数而 isInstanceOf 不能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是 REPL (scala 2.11) 中的人为实验:

Here's the contrived experiments in REPL (scala 2.11):

scala> class Foo[T] {
     |   def as(x: Any) = x.asInstanceOf[T]
     | }

defined class Foo

scala> val foo = new Foo[String]
foo: Foo[String] = Foo@65ae6ba4

scala> val x: Any = 123
x: Any = 123

scala> foo.as(x)  // expected
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
  ... 33 elided

scala> val y: Any = "abc"
y: Any = abc

scala> foo.as(y)
res1: String = abc


scala> class Bar[T] {
     |   def is(x: Any) = x.isInstanceOf[T]
     | }

<console>:12: warning: abstract type T is unchecked since it is eliminated by erasure
         def is(x: Any) = x.isInstanceOf[T]
                                        ^
defined class Bar

scala> val bar = new Bar[String]
foo: Foo[String] = Foo@1753acfe

scala> val x: Any = 123
x: Any = 123

scala> bar.is(x)  // unexpected
res2: Boolean = true

scala> val y: Any = "abc"
y: Any = abc

scala> bar.is(y)
res3: Boolean = true

我知道由于类型擦除,类型参数非常有限,但仍然对这里 asInstanceOf 和 isInstanceOf 之间的不同行为感到困惑.

I know type parameter is quite limited due to type erasion, but still confused by the different behaviours between asInstanceOf and isInstanceOf here.

想知道是否有人对此有任何见解?谢谢!

Wonder if someone has any insight about that? Thanks!

推荐答案

好吧,你必须知道,类型参数在运行时是不可用的,它们携带的所有信息只能被编译器使用.现在,asInstanceOf 只是一个强制转换,编译器只需要它来强制类型兼容性,并且在运行时它根本不做任何事情:引用就是引用,关于类型基础对象.

Well, you must know, that type parameters are not available at runtime, all information they carry can only be used by the compiler. Now, asInstanceOf is just a cast, it is only needed to the compiler to enforce the type compatibility, and at runtime it doesn't do anything at all: a reference is a reference, regarding of the type of underlying object.

isInstanceOf 另一方面则相反:编译器对此一无所知,它只是一个函数调用.它在运行时执行以检查给定对象是否为预期类型.但是类型参数在运行时不可用,那么它如何知道要检查哪种类型呢?为此,它需要一个真正的 Class 参数.

isInstanceOf on the other hand is the opposite: compiler does not know anything about it, it's just a function call. It is executed at runtime to check whether the given object is of the expected type. But the type parameter is not available at runtime, so how would it know which type to check against? For this reason, it needs a real Class argument.

这篇关于Scala:为什么 asInstanceOf 可以接受类型参数而 isInstanceOf 不能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆