Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.Integer cannot be cast to java.lang.Byte error with Any type in Scala

Tags:

types

scala

I can cast Int data to Byte.

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

However with the same value in Any type, the cast raises an error.

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)

I can cast twice.

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

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

Are there better ways than this?

like image 351
prosseek Avatar asked Dec 25 '22 05:12

prosseek


2 Answers

Try converting to int and then to Byte:

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

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

Or as Ionuț G. Stan suggested:

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

Although I cannot explain why this work.

like image 30
Ende Neu Avatar answered Mar 01 '23 23:03

Ende Neu


In Scala, compiler tries to hide the distinction between primitive types and reference ones (boxed), defaulting to primitives. Sometimes, abstractions leak and you see that kind of problems.

Here, you're pretending that value is Any, which require compiler to fallback to boxed values:

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

And here, you're not limiting value to be referential, so such casting will be done on primitive types:

10.asInstanceOf[Byte]

In other words:

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

To overcome this problem, you probably have to go through an extra conversion to, say, String:

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

scala> x.toString.toByte
res7: Byte = 10
like image 78
om-nom-nom Avatar answered Mar 02 '23 01:03

om-nom-nom