in Programming, Tips

Kotlin Basics: Java Interop and the Reflection Operator

Kotlin’s interoperability with existing Java code is excellent. Most of the time, you simply use Java code inside of your Kotlin classes, and it works out of the box. There are a couple of situations, though, where you have to explicitly tell Kotlin to bridge the gap. The most common one are Java factory methods, where you supply a Class parameter and get an instance back. Most of the widely used Java libs have such methods. Let’s have a look at Retrofit:

The main Retorfit class has a create method, which accepts a Class parameter, and returns an instance

public <T> T create(final Class<T> service) {
  // ...
}

When calling this from Kotlin, the first assumption is that it will work the same way as good old Java code did:

val retrofit = Retrofit.Builder().baseUrl("https://someurl.com").build()
val myApi: MyApi = retrofit(MyApi.class)

Yet, the second line produces an error. Turns out that in Kotlin, reflection references (such as class, function and property ones) can only be accessed via a special operator named refelection operator (::). In fact, accessing the class of a variable then looks like this:

val myApi: MyApi = retrofit(MyApi::class)

Keep in mind though that ::class actually refers to the Kotlin class (aka KClass) and it won’t get accepted by Java code either. A KClass is just an abstraction on top of a Java class, providing some more introspection capabilities. One of its properties, .java is exactly what we want – a plain old Class instance. So the code above looks like this now:

val retrofit = Retrofit.Builder().baseUrl("https://someurl.com").build()
val myApi: MyApi = retrofit(MyApi::class.java)

Bridging between Kotlin and Java in this way can be a bit annoying, but generally, it occurs far less than one thinks. One just needs to be aware that sometimes, a bit of minor plumbing code is necessary.