A Study: How Retrofit, written in Java, interpolates Kotlin's Coroutines to enable `suspend` functions
A Study: How Retrofit, written in Java, interpolates Kotlin's Coroutines to enable suspend functions
In the modern Android development ecosystem, the synergy between Kotlin and Java is quite still important since many of very traditional projects are written in Java. A prime example of this great interoperability is Square's Retrofit library. Despite being written entirely in Java, Retrofit seamlessly supports Kotlin's suspend functions, allowing developers to write clean, idiomatic asynchronous code for network requests. This capability is not magic, it is a sophisticated illusion built upon a cooperative understanding between the Kotlin compiler and Retrofit's dynamic, reflection-based architecture.
This study examines the internal mechanisms that make this "interpolation" possible, revealing how a Java library can interact with a language feature it has no native concept of.
The Foundation: Continuation-Passing Style (CPS) Transformation
The cornerstone of Kotlin's suspension mechanism is a compiler transformation known as Continuation-Passing Style (CPS). When the Kotlin compiler processes a suspend function, it fundamentally rewrites its signature and body to be compatible with the Java Virtual Machine (JVM), which does not have a built-in concept of coroutines.
Consider a simple suspend function defined in a Retrofit interface:
interface ApiService {
@GET("user/{id}")
suspend fun getUser(@Path("id") userId: String): User
}
From the perspective of a Kotlin developer, this is a function that can be paused and resumed. However, for the JVM, the compiler transforms it into a standard Java method with a modified signature. Conceptually, the compiled bytecode looks like this:
This article continues for subscribers
Subscribe to Dove Letter for full access to 40+ deep-dive articles about Android and Kotlin development.
Become a Sponsor