【问题标题】:java.lang.Integer cannot be cast to java.lang.Byte error with Any type in Scalajava.lang.Integer 无法转换为 java.lang.Byte 错误,Scala 中的 Any 类型
【发布时间】:2014-08-13 22:34:22
【问题描述】:

我可以将 Int 数据转换为字节。

scala> 10.asInstanceOf[Byte]
res8: Byte = 10

但是在 Any 类型中使用相同的值,强制转换会引发错误。

scala> val x : Any = 10
x: Any = 10

scala> x.asInstanceOf[Byte]
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Byte
    at scala.runtime.BoxesRunTime.unboxToByte(BoxesRunTime.java:98)
    at .<init>(<console>:10)

我可以施放两次。

scala> val y = x.asInstanceOf[Int]
y: Int = 10

scala> y.asInstanceOf[Byte]
res11: Byte = 10

还有比这更好的方法吗?

【问题讨论】:

  • 请注意,您不需要10.asInstanceOf[Byte]10.toByte 工作得很好。

标签: scala types


【解决方案1】:

在 Scala 中,编译器试图隐藏原始类型和引用类型(装箱)之间的区别,默认为原始类型。有时,抽象会泄漏,您会看到这类问题。

在这里,您假装该值为 Any,这需要编译器回退到装箱值:

override def set(value:Any) = {
    if (check(value.asInstanceOf[Byte])) {

在这里,您并没有限制引用的值,所以这种转换将在原始类型上完成:

10.asInstanceOf[Byte]

换句话说:

scala> val x: Any = 10
x: Any = 10

scala> x.asInstanceOf[Byte]
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Byte
  at scala.runtime.BoxesRunTime.unboxToByte(BoxesRunTime.java:97)
  ... 32 elided

scala> val y: Int = 10
y: Int = 10

scala> y.asInstanceOf[Byte]
res4: Byte = 10

要克服这个问题,您可能需要进行额外的转换,例如字符串:

scala> x.toString.toInt
res6: Int = 10

scala> x.toString.toByte
res7: Byte = 10

【讨论】:

  • +1,因为您的回答确实解释了为什么会发生这种情况,这种回归形式 Any 到 java 原始类型是否仅在尝试将类型从 Any 转换为某个子类型时发生?
  • 我喜欢这个解释,但不太喜欢这个解决方案。我会选择@EndeNeu 的。
  • @EndeNeu 当他们被装箱时,所以with AnyVal as well (see the second sentence)
  • @IonuțG.Stan 好的。顺便说一句,或者,您可以显式地拆箱值:scala.runtime.BoxesRunTime.unboxToInt(y).asInstanceOf[Byte]
  • @om-nom-nom 对此一无所知。谢谢!
【解决方案2】:

尝试转换为 int,然后转换为 Byte:

scala> val x : Any = 10
x: Any = 10

scala> x.asInstanceOf[Int].asInstanceOf[Byte]
res1: Byte = 10

或者正如 Ionuț G. Stan 建议的那样:

scala> x.asInstanceOf[Int].toByte
res4: Byte = 10

虽然我无法解释为什么会这样。

【讨论】:

  • +1 不过,我会将x.asInstanceOf[Int].asInstanceOf[Byte] 替换为x.asInstanceOf[Int].toByte
  • 这个工作的原因是因为你要转换为任何东西的超类型,即Any,然后向下转换为字节。这是scala中的类型层次结构scala-lang.org/old/node/128
  • @ChrisStewart 感谢您的解释,感谢 Ionut 的精彩捕获。
【解决方案3】:

Java 中整数是 32 位,而字节显然是 8 位。问题是你截断了哪些位以使整数成为一个字节?最低有效 24 位还是最高有效 24 位?正确的答案是在你的问题的背景下。

【讨论】:

    猜你喜欢
    • 2014-05-05
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多