mardi 25 février 2020

Does the use of `is` in a when expression over a sealed class result in reflection at runtime?

In Java, if I have a class hierarchy like so:

private interface Foo { }

private class FooBar implements Foo { }

private class FooZoo implements Foo { }

And then I have a function like so:

public int Return0IfFooBarElseIfFooZooReturn1ElseReturn2(Foo foo) {
    if (foo instanceof FooBar) {
        return 0;
    } else if (foo instanceof FooZoo) {
        return 1;
    } else {
        return 2;
    }
}

At run time, reflection will be used to determine the type of foo. In an ideal world, we would like to avoid having our code use reflection. In addition, as far as I know, there is no way to create a sealed type hierarchy in Java, meaning you will always need to provide an else branch to have the code compile.

However in Kotlin you can create a sealed type hierarchy, like so:

sealed class Foo {
  object FooBar : Foo()
  object FooZoo : Foo()
}

And you can then write a when expression to switch on the type and return a value like so:

fun return0IfFooBarElseReturn1(foo: Foo) = when (foo) {
  is Foo.FooBar -> 0
  is Foo.FooZoo -> 1 
}

There is an interesting property about this; namely, there is no need for an else, because the when expression is exhaustively checking the sealed type hierarchy. So, from this property, can the compiler derive enough information in order to compile bytecode which somehow is not going to use reflection at runtime to determine if the passed instance is of a given type?

Or in other words, is there any difference (with regards to reflection) at run time between the Kotlin code above, and the Kotlin code below:

interface Foo

class FooBar : Foo { }

class FooZoo : Foo { } 

fun return0IfFooBarElseReturn1(foo: Foo) = when (foo) {
    is FooBar -> 0
    else -> 1
}

I am asking this, because generally as programmers, we would like to avoid reflection (where possible), but the official Kotlin docs for sealed classes show an example of switching on an instance using is (https://kotlinlang.org/docs/reference/sealed-classes.html). I also do this a fair bit in the code I do at work, and whilst I don't really see any issue with doing it, some co-workers have voiced concerns as it looks like a code smell.





Aucun commentaire:

Enregistrer un commentaire