Twórcy Kotlina chwalą się super-duper interoperability między Kotlinem a Javą, i jest to w zasadzie prawdą. Niech za przykład posłuży nam to, że choć w Javie klasy reprezentowane są przez obiekty typu
java.lang.Class<T>
a w Kotlinie przez
kotlin.reflect.KClass<T>
to jednak bardzo łatwo można wyłuskać jeden z drugiego:
val longTypeKotlin = Long::class
val longTypeJava = longTypeKotlin.java
val booleanTypeJava = Boolean::class.java
val booleanTypeKotlin = booleanTypeJava.kotlin
Nic nie stoi zatem na przeszkodzie, żeby wyłuskać KClass<T>
z obiektu Class<T>
wyłuskanego z KClass<T>
. Widzicie, dokąd to zmierza?
Dokładnie, nie tylko poniższa funkcja skompiluje się bez zająknięcia:
fun fizz(): Boolean {
val foo: KClass<Long> = Long::class
val bar: KClass<Long> = Long::class.java.kotlin
return foo.equals(bar)
}
ale ta również, w końcu tymi dwoma typami można sobie żonglować bez końca:
fun buzz(): Boolean {
val foo: Class<Long> = Long::class.java
val bar: Class<Long> = Long::class.java
.kotlin.java.kotlin.java.kotlin.java.kotlin.java.kotlin.java
.kotlin.java.kotlin.java.kotlin.java.kotlin.java.kotlin.java
.kotlin.java.kotlin.java.kotlin.java.kotlin.java.kotlin.java
.kotlin.java.kotlin.java.kotlin.java.kotlin.java.kotlin.java
.kotlin.java.kotlin.java.kotlin.java.kotlin.java.kotlin.java
.kotlin.java.kotlin.java.kotlin.java.kotlin.java.kotlin.java
.kotlin.java.kotlin.java.kotlin.java.kotlin.java.kotlin.java
return foo.equals(bar)
}
Co więcej, obie się wykonają i zwrócą nam wartości true
:
fun main(args: Array<String>) {
print("fizz() says '${fizz()}' while buzz() says '${buzz()}'")
}
fizz() says 'true' while buzz() says 'true'
Co samo w sobie jest właściwie nieszkodliwe, a komuś być może się nawet przydało, choć i tak wywołuje małe WTF.
Duże WTF wywołuje u mnie fakt, że dla IntelliJ - nomen omen IDE tworzonego przez twórców Kotlina - taka machinacja jak w fun buzz()
jest jak najbardziej OK i nawet się nie zająknie, że ta operacja w tym miejscu jest pozbawiona sensu i można by ją uprościć :)