Search code examples
javakotlin

Should Kotlin sealed interfaces be exhaustive in Java switch expressions?


Using Java type patterns in switch expressions with sealed Java interfaces is really nice:

sealed interface AOrB permits A,B { }
// ...
AOrB aOrB = ...;
// ...
switch (aOrB) {
    case A a -> foo(a);
    case B b -> bar(b);
    // no default case needed, as aOrB *has to* be of type A or B
}

Unfortunately, doing the same with Kotlin seems not possible:

sealed interface AorB {
    data class A() : AorB
    data class B() : AorB
}

Using this Kotlin interface in a Java switch expression the same way as above gives me the compile error 'switch' expression does not cover all possible input values. Do I need to apply some tricks to make the Kotlin sealed interface exhaustive in plain old Java? Or is this a bug in Kotlin?


Solution

  • This has been reported as KT-68183.

    In a related issue, it is mentioned that,

    Also, the interop support between Java and Kotlin around sealed classes/interfaces is not clear yet

    So it is not yet decided how Kotlin sealed classes/interfaces should be seen by Java code.

    For now, you can write a when in Kotlin code if you want. The Kotlin compiler can check that this is indeed exhaustive. You can easily put this into a function that is then called from Java code.

    fun doSomething(aOrB: AorB) = when(aOrB) {
        is AorB.A -> foo(aOrB)
        is AorB.B -> bar(aOrB)
    }
    
    // then you can just call doSomething from your Java code!