Java Interop
How Kotlin and Java call each other: platform types at the nullability boundary, SAM conversions, the @Jvm annotations that shape emitted members, type mapping, and the traps in between. Every real Kotlin codebase is a mixed codebase, so this comes up constantly.
part ofKotlinoverview, primer and where to startread it →on this pageshowhide
explore
- How Kotlin Interops With Java5 questions
- Calling Java From Kotlin30 questions
- Platform Types & Nullability5 questions
- Java Getters/Setters As Properties5 questions
- SAM Conversions5 questions
- Java Arrays & Varargs5 questions
- Java Collections As (Mutable) Views5 questions
- Java Statics, Fields & Checked Exceptions5 questions
- Calling Kotlin From Java31 questions
- @JvmStatic5 questions
- @JvmField5 questions
- @JvmOverloads5 questions
- @JvmName & @file:JvmName5 questions
- @Throws For Checked Exceptions5 questions
- Companion & Top-Level Access From Java6 questions
- Type Mapping Mechanics25 questions
- Kotlin <-> Java Type Mapping5 questions
- Unit, Nothing & void Mapping5 questions
- Default-Argument Bridge Methods5 questions
- Property & Field Exposure5 questions
- Interface Default Methods (DefaultImpls)5 questions
- Boundary Pitfalls25 questions
- Null-Safety Holes At The Boundary5 questions
- Synthetic $ Members5 questions
- Name Mangling (internal & value classes)5 questions
- Use-Site Annotation Targets5 questions
- JVM Signature Clashes5 questions
questions
116 · 5 sectionsWhat is a platform type in Kotlin, why does it exist, and what risk does it introduce?
basics
~20 sWhen Kotlin calls Java, Java values have no nullability info, so Kotlin can't tell if they can be null. It treats them as 'platform types' and trusts you. If you assume non-null but it's actually null, you get an NPE.
What do @JvmStatic, @JvmField, @JvmName, @JvmOverloads, and @JvmMultifileClass do, and when would you reach for each?
basics
~20 sThese @Jvm* annotations change the Java-facing shape of compiled Kotlin so Java can call it naturally — making members static, exposing plain fields, renaming, generating overloads for default arguments, or merging top-level functions into one class.
Explain how Kotlin maps types to the JVM: mapped types, primitives vs boxing, and what happens to Kotlin-only types like Unit and Nothing.
basics
~20 sMany Kotlin types are just renamed JVM types (Kotlin String is Java String). Numbers use fast primitives when possible and box only when they must be nullable or generic. Unit becomes void-like; some types like Nothing have no real runtime value.
When mixing Kotlin and Java, how do SAM conversions, Kotlin properties, and the read-only/mutable collection split behave across the boundary?
basics
~20 sA Kotlin lambda can stand in for a Java single-method interface (SAM conversion). Kotlin properties show up as getX/setX to Java. And Kotlin's read-only vs mutable list distinction disappears at runtime, so Java can still mutate a 'read-only' list.
When you call a Java method that takes an int[] from Kotlin, what Kotlin type do you pass, and why not Array<Int>?
basics
~10 sUse Kotlin's IntArray for a Java int[]. Array<Int> is an array of boxed Integer objects (Integer[]), which is a different Java type and won't match an int[] parameter.
In Kotlin, what is the difference between List and MutableList, and where does that distinction actually exist at runtime?
basics
~20 sList has no add or remove methods, MutableList does. But it's only a rule the compiler checks. At runtime both are usually the same Java ArrayList, so the read-only promise can be broken from Java code.
When you call a Java class from Kotlin, how do you read a value exposed by a Java getter like getName()? Show both ways Kotlin lets you access it.
basics
~10 sKotlin lets you write obj.name instead of obj.getName(). It turns Java get/set methods into a property you read and write with a dot. You can still call obj.getName() the old way too.
How do you call a Java static method and read a Java static field (like Integer.parseInt or Integer.MAX_VALUE) from Kotlin?
basics
~10 sYou call them directly on the class name, just like in Java: Integer.parseInt("42") and Integer.MAX_VALUE. There is no special import or wrapper needed.
What is a Kotlin platform type, why does it show up as String! in the IDE, and what happens to null checking when you use one?
basics
~20 sA platform type is a value coming from Java whose nullability Kotlin can't know. The compiler relaxes null checks for it. If you treat it as non-null but it's actually null, you get a NullPointerException at runtime.
You have a Kotlin class with a companion object containing a function create(). How do you call that function from Java, and why isn't the call simply Foo.create()?
basics
~10 sFrom Java you call Foo.Companion.create(). Kotlin puts companion members on a nested object named Companion, so Java must go through that object rather than calling the method straight on the class.
A Kotlin file Utils.kt declares a top-level function fun greet(): String. How does Java call it, and where does that method actually live on the JVM?
basics
~10 sKotlin puts top-level functions into an auto-generated class named after the file plus 'Kt'. So Utils.kt's greet() is called from Java as UtilsKt.greet().
What does the @JvmField annotation do, and why would you use it when calling Kotlin code from Java?
basics
~10 s@JvmField turns a Kotlin property into a plain public field. Java code can then read or write it directly as obj.x instead of calling getX() or setX().
What does the @JvmName annotation do, and why would you put it on a Kotlin function or property accessor that Java code will call?
basics
~20 s@JvmName changes the name that a Kotlin function, getter, or setter shows up as when called from Java. It lets you give Java a nicer name or avoid a name conflict, without changing the Kotlin name.
What does the @JvmOverloads annotation do, and why is it needed for Java callers?
basics
~10 sJava cannot use Kotlin's default argument values. @JvmOverloads tells the compiler to also generate extra Java-visible overloads, one per default-parameter combination, so Java code can call the function while leaving some arguments out.
You write a Kotlin function fun greet(name: String, greeting: String = "Hello"). A Java colleague says they can only call it by passing both arguments. Why can't Java omit the defaulted parameter, and what is the simplest fix?
basics
~10 sKotlin default values live only in Kotlin metadata, not in the compiled method signature Java sees. So Java must pass every argument. Adding @JvmOverloads makes Kotlin also generate the shorter overloads Java can call.
When a Kotlin interface has a method with a body (a default implementation), how is that body compiled for the JVM by default, and what is the DefaultImpls class?
basics
~20 sKotlin lets interface methods have a body. By default the compiler does not put that body on the JVM interface itself; it copies it into a hidden helper class so classes implementing the interface can reuse it.
When you declare `var count: Int` in a Kotlin class, what does Java code see when it uses that class?
basics
~10 sJava does not see a public field. It sees a private hidden field plus two methods: getCount() to read it and setCount() to change it. Java must call those methods.
When you write a Kotlin function that takes a kotlin.Int parameter, what Java type does it become in the compiled bytecode, and when would it instead become java.lang.Integer?
basics
~20 sKotlin's Int usually compiles to Java's primitive int, which is fast and uses no extra memory. But when the value can be null or is used as a generic type argument, Kotlin boxes it into Integer instead.
How does a Kotlin function that returns Unit appear when called from Java, and what is the JVM bytecode return type?
basics
~10 sA Kotlin function returning Unit looks like a normal void method in Java. The JVM return type is void, so Java callers just call it and get nothing back.
What is a 'platform declaration clash' in Kotlin, and what commonly causes it?
basics
~10 sIt is a compile error that happens when two Kotlin functions look different in Kotlin but turn into the exact same method on the JVM, so the JVM cannot tell them apart.
What is a Kotlin 'platform type' and why can a value coming from Java code throw a NullPointerException even though your Kotlin code looks fully null-safe?
basics
~20 sWhen Java returns a value, Kotlin doesn't know if it can be null, so it trusts you. If you treat it as non-null and it actually is null, you only crash later when you use it.
When a Java developer calls into a Kotlin class that has a companion object, what is the 'Companion' field they see in autocomplete, and how should they reach the companion's members from Java?
basics
~10 sKotlin turns a companion object into a static field named Companion plus a nested class. From Java you call MyClass.Companion.method(), unless the member is annotated @JvmStatic, which lets you call MyClass.method() directly.
In Kotlin, what is a use-site annotation target, and why might you write `@field:NotNull` instead of just `@NotNull` on a property?
basics
~10 sA single Kotlin property turns into several Java elements (field, getter, setter, constructor parameter). A use-site target like @field: tells the compiler which of those elements the annotation should land on.
Show how to resolve a generic-erasure platform clash for two overloads using @JvmName, and explain what each annotation changes.
basics
~10 sPut @JvmName with a different name on at least one of the clashing functions. That gives each a unique method name in the compiled code, so the JVM no longer sees a duplicate.