You can try to run this code. It’s very confused u...
# announcements
j
You can try to run this code. It’s very confused until I looked at the compiled bytecode
s
It's not reified, so
origin as? T
isn't a safe cast at all, it's always going to be unsafe
s
also casting a string, doesn’t make it an Int. that’s what
toInt()
is for as in
val i = "123".toInt()
here is the casting solution, though it seems you can’t even cast from Long or Double to Int, as you would in Java. But the principle works:
Copy code
fun main() {
	println("test")
    val anyInt = 125 as Any
    println (anyInt)
  	val backAsInt = cast<Int>(anyInt)
    println(backAsInt)
}

inline fun <reified T> cast(origin: Any): T? = origin as? T
k
No I agree, this doesn't make any sense. Unchecked casts usually just lower to the generic bound, so that functions should just return
null
in this case. It works fine if you flip
String
and
Int
in the code.
I think this is a bug, report to YouTrack.
j
Yes. That’s my point. The cast should return “null” as we expected(as?). But it tried to return
int
which will cause NullPointerException due to the
Integer.toInt
.
s
It can't return
null
, because you're casting to an erased type T. That's why the compiler complains about an unchecked cast
j
Yes, after erase, should it return
Integer
? If you change the
T: Int
to such as
T: Shape
, it will print null. The whole point here is that it throws NPE which is not expected. If I’m not looking at the bytecode, I have no idea why it returns NPE - It throws NPE because the compiler makes the
cast
method to return
int
instead of
Integer
, then the NPE throws due to the
Integer.toInt()
should the
as?
operator always return you reference type? Does it make sense that optimizing the return type to primitive type?
k
Kotlin the language avoids the concept of boxed types, it's only the backends that then try to emit primitive code. This is just a bug related to that.