On this page
"How would you migrate our 300k-line Java app to Kotlin?" is a common senior question. The best answers show you understand interop deeply, migrate incrementally with safety nets, and focus effort where it delivers value.
Interop questions
What are platform types?
Types from Java without nullability information (shown as String!). Kotlin lets you treat them as nullable or non-null, and a wrong assumption causes an NPE at runtime. Fix it with @Nullable/@NonNull annotations on the Java side.
How do you make Kotlin APIs pleasant to call from Java?
class Prices {
companion object {
@JvmStatic fun format(amount: Double): String = "โน%.2f".format(amount) // Prices.format(...) in Java
const val CURRENCY = "INR" // a true Java constant
}
}
@JvmOverloads fun toast(context: Context, text: String, long: Boolean = false) { /* ... */ } // overloads for Java
// In a separate file, as its very first line (before the package statement):
// @file:JvmName("StringUtils") โ top-level functions appear as StringUtils.xxx() in JavaHow do Kotlin properties appear in Java?
As getters and setters (getName()/setName()), with isX() for properties starting with "is". Use @JvmField to expose a field directly.
Checked exceptions?
Kotlin has none. If Java callers must catch an exception, declare it with @Throws(IOException::class).
Suspend functions from Java?
They're awkward (an extra Continuation parameter). Provide Java-friendly wrappers, such as callbacks or futures, at the boundary.
Strategy questions
How would you prioritise what to convert?
Convert files you're actively changing, plus high-value areas such as frequently changed features, crash hotspots and code that would benefit from coroutines or Compose. Leave stable, rarely touched Java alone until there's a reason.
How do you keep behaviour unchanged?
Write characterization tests before converting, keep conversion commits separate from refactors and features, and review converted code for semantics changes (equals/hashCode, nullability, static initialisation).
What does the automatic converter get wrong?
It produces working but non-idiomatic code: !! and lateinit overuse, Java-style getters, mutable collections, missed data classes and sealed types. It needs a manual idiomatic pass.
Subtle bugs
| Pitfall | Example |
|---|---|
| Nullability assumptions | Converted field declared non-null but Java callers pass null โ crash |
| Equality changes | Converting a class to a data class changes equals semantics (maps, sets, DiffUtil) |
| Static initialisation | companion object initialisation timing differs from Java static blocks in edge cases |
| SAM conversions | Kotlin lambdas vs Java functional interfaces; fun interface for Kotlin-declared SAMs |
| Annotation processing | kapt vs KSP migration effects on build time and generated code |
Build and team questions
- Build time: mixed projects compile both languages. Kotlin's K2 compiler and KSP (instead of kapt) help.
- Team: agree on Kotlin style (official conventions plus a linter), review idioms, and pair on early conversions.
- Measure progress: the percentage of Kotlin files is a vanity metric. Track crash rate, delivery speed and test coverage in converted areas.
Frequently asked questions
Should we convert everything?
Not necessarily. Kotlin and Java interoperate well. Convert where it pays off, and let stable Java code be.
Can AI tools help migrate?
Yes, for drafting conversions and explanations, with careful review and tests. See AI for Legacy Java.
Conclusion
Strong migration answers combine interop knowledge (platform types, Jvm annotations, exceptions), an incremental strategy with tests and separate commits, awareness of subtle semantic changes, and team practices that keep the codebase consistent.
Next step: think about the future of the role in How AI Is Changing the Work of Android Developers.
Official references
๐ฑ Apps built by Yunok Tech
Real Android apps on Google Play, free to download.
Walzi4K wallpapers for lock and home screenGet it โธ
NotiVaultNotification history: recover dismissed notificationsGet it โธ
Ready to build real Android applications?
Kotlin fluency makes everything else in Android easier, from coroutines and Flow to Compose and clean architecture. The fastest way to build that fluency is to write real Kotlin every day and get feedback on it.
Move beyond theory and strengthen your Android development skills with Yunoktech's Android course. Learn core concepts, practical implementation, modern Android development techniques, and the reasoning behind building maintainable applications.
Explore the Android course and take your next step as an Android developer.