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?
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With