java.lang.CharSequence as a member of a Java class is not type-checked as expected

Viewed 85

The following code is rejected by the Kotlin compiler (rightfully so):

// main.kt
class KotlinFoo(val bar: java.lang.CharSequence)

fun test(foo: KotlinFoo) {
    println(foo.bar == "hi")
}

Error:

Operator '==' cannot be applied to 'CharSequence' and 'String'

The following, however, is accepted without complaints:

// JavaFoo.java
public class JavaFoo {
    public java.lang.CharSequence bar;
}
// main2.kt
fun test(foo: JavaFoo) {
    println(foo.bar == "hi")
}

I would have expected it to generate the same error.

Is this compiler behavior intended?

1 Answers

That's because kotlin.String "hi" is guaranteed to be not java.lang.CharSequence but kotlin.CharSequence. These classes have different subtyping hierarchies.

So, you should use kotlin.CharSequence in all cases, because on JVM it is mapped to java.lang.CharSequence by the ecompiler anyway.

However, there is a hack if you really want to use Java types in Kotlin—you can cast Kotlin's char sequences to Java ones:

    val s: java.lang.CharSequence = "42" as java.lang.CharSequence
    println(s == "42" as java.lang.CharSequence)
Related