基于`Class`实例执行显式转换

时间:2016-10-25 14:12:14

标签: scala scala-reflect

假设有一个班级X。在我的代码中的某个时刻,我得到了o类型Object,我想明确地将其转换为X。通常情况下,我会做val x: X = o.asInstanceOf[X]。但是,X不在范围内,我只有X Class的实例,如下所示:

  1. 我将classOf[X]作为名为classOfX的参数传递给我的函数。
  2. 在我的职能范围内,我想val x: X = o.asInstanceOf[classOfX]
  3. 有没有办法在Scala中执行此操作?

1 个答案:

答案 0 :(得分:2)

只有一种。 java.lang.Classcast方法,可让您将Class[A]投射到A。你可以写一个像这样的方法:

def cast[A](o: Any, clazz: Class[A]): A = clazz.cast(o)

scala> cast("abc", classOf[String])
res10: String = abc

对于大多数类来说,这将“起作用”,但不适用于Scala盒装基元:

scala> cast(1, classOf[Int])
java.lang.ClassCastException: Cannot cast java.lang.Integer to int

当然,转换只能模拟类型擦除,所以这不会立即引发异常:

scala> val a = List("a").getClass
a: Class[_ <: List[String]] = class scala.collection.immutable.$colon$colon

scala> cast(List(1), a)
res16: List[String] = List(1)

从好的方面来说,它也适用于在运行时使用getClass获得的类,如上所述。

缺点是你应该不惜一切代价避免投射,因为它会使代码容易出错。它将窗户的类型安全抛出。很少有人发现自己处于一个他们不知道它是什么的对象的情况,但可以某种方式告诉编译器使用classOf的内容。使用某种形式的泛型可能会消除一个转换问题,但如果没有更多的代码则无法判断。