Why doesn't 'is' type check work on Java classes


#1

Hi, could someone explain me why does “is” typecheck fail in such a simple scenario when checking Java class from Kotlin code:

//JavaClass.java
public class JavaClass {}

//Kotlin.kt
open class Base
class Derived : Base()
class SomeOtherKotlinClass

fun test1(base : Base) = base is Derived //compiles, as expected
fun test2(base : Base) = base is SomeOtherKotlinClass //fails, as expected
fun test3(base : Base) = base is JavaClass //compiles, but should also fail as JavaClass does not derive from Base

#2

I don’t know how you test code written.
My test code:

fun main(args: Array<String>) {
    println(test3(Base())) // false
    // println(test2(Base())) Can't compile test2 func
    println(test1(Base())) // false
}

Maybe I misunderstood your “fail”.
If you meant test2 couldn’t be compiled while test3 could, it’s may because Kotlin can’t apply type checking stricty to Java types.


#3

yeah, runtime check works, I’m talking about compile time check. I wonder why does it not work and are there any plans to implement it?


#4

is operator in Kotlin will be simply compiled to the same bytecode as instanceof operator in Java.
For example, the function below

fun testIs(any: Any?) = any is String

will be compiled to

aload 0
instanceof java/lang/String
ireturn

Both Kotlin’s is and Java’s instanceof operator will give your a compile error when you are trying to apply an instance to a incompatible type.

//Java Test 
System.out.println(new StringBuilder() instanceof String); // compile error
//Kotlin Test
println(StringBuilder() is String) // compile error

Compile errors only disappear when you are applying an instance to a Java type which hasn’t mapped to a Kotlin type.
The Kotlin test code above works because kotlin.String is a Kotlin type. You could find all the mapped types here: Mapped Types
Also something about Platform Types