Reference (it’s Chinese so I’ll translate the important part here): https://lgzh1215.github.io/2017/10/18/huadian/
We have:
class A<T : Any>(val data: T)
class B(val string: String)
fun test(a: A<*>) {
a.data as B // mention the bytecode corresponds to this line
a.data.string // a.data is Smart casted to B
}
And we look at the generated bytecode:
...
L1
LINENUMBER 5 L1
ALOAD 0
INVOKEVIRTUAL A.getData ()Ljava/lang/Object; // a.data
DUP
IFNONNULL L2 // <============================ null check
NEW kotlin/TypeCastException
DUP
LDC "null cannot be cast to non-null type B"
INVOKESPECIAL kotlin/TypeCastException.<init> (Ljava/lang/String;)V
ATHROW
L2
CHECKCAST B // <============================ if NotNull then cast
POP
L3
...
It checks if a.data
is null. If not
, throw TypeCastException("null cannot be cast to non-null type B")
.
However, according to the definition of a.data
, it should always be a NotNull variable.
So it’s impossible for a.data
to be null.
Which means the null check is redundant.
Although I can cast it to a Nullable, this is an unignorable bug.
This happens in Kotlin 1.1 .
Any ideas?