Question
I defined an extension function in a Kotlin file and want to call it from Java code.
Here is the Kotlin code:
package com.test.extensions
import com.test.model.MyModel
fun MyModel.bar(): Int {
return this.name.length
}
MyModel is a generated Java class. I then tried to call the extension function from Java like this:
MyModel model = new MyModel();
model.bar();
However, this does not work. The IDE does not recognize bar() as a method on MyModel, and compilation fails.
A normal top-level Kotlin function does work from Java. For example:
fun bar(): Int {
return 2 * 2;
}
and I can access it from Java through the generated class for the Kotlin file.
So what am I doing wrong? Is it possible to access Kotlin extension functions from Java, and if so, how should they be called?
Short Answer
By the end of this page, you will understand why Kotlin extension functions do not appear as real instance methods in Java, how Kotlin compiles them, and the correct way to call them from Java using the generated class and a static method call.
Concept
Kotlin extension functions let you write code that looks like you are adding a new method to an existing class:
fun MyModel.bar(): Int = this.name.length
In Kotlin, this can be called like:
val result = model.bar()
That syntax is convenient, but it is important to understand what extension functions really are.
Extension functions do not modify the class
An extension function does not actually add a method to MyModel. It is only a Kotlin language feature. Under the hood, Kotlin compiles that function into a static function.
So this Kotlin code:
fun MyModel.bar(): Int = this.name.length
is compiled to something conceptually like this for Java:
public static int bar(MyModel receiver) {
return receiver.getName().length();
}
Mental Model
Think of an extension function like a helper tool placed next to an object, not a new part installed inside the object.
model.bar()in Kotlin is like saying, "use the helper tool as if it belongs tomodel"- In reality, the tool lives outside the object
- Java only sees the actual object and its real methods, not Kotlin's syntactic shortcut
So Kotlin gives you a friendly shortcut:
model.bar()
But Java sees the real form:
ExtensionsKt.bar(model)
A useful analogy:
- Real method: a button built into a machine
- Extension function: a remote control that works with the machine
Kotlin lets the remote feel like a built-in button. Java does not.
Syntax and Examples
Core syntax in Kotlin
An extension function is declared by writing the target type before the function name:
fun TypeName.functionName(): ReturnType {
// use this to refer to the receiver object
}
Example:
fun String.firstChar(): Char {
return this[0]
}
Used in Kotlin:
val letter = "Hello".firstChar()
println(letter) // H
Your example
Kotlin:
package com.test.extensions
import com.test.model.MyModel
fun MyModel.bar(): Int {
return this.name.length
}
If the file is named Extensions.kt, Java calls it like this:
Step by Step Execution
Consider this Kotlin file Extensions.kt:
package com.test.extensions
import com.test.model.MyModel
fun MyModel.bar(): Int {
return this.name.length
}
And this Java code:
import com.test.extensions.ExtensionsKt;
import com.test.model.MyModel;
MyModel model = new MyModel();
int result = ExtensionsKt.bar(model);
What happens step by step
1. Kotlin compiles the extension function
Kotlin does not insert bar() into the MyModel class.
Instead, it generates something equivalent to a static method in a helper class:
public final class ExtensionsKt {
{
receiver.getName().length();
}
}
Real World Use Cases
Extension functions are commonly used in Kotlin-heavy codebases, even when Java is also present.
Practical uses
Formatting domain objects
fun MyModel.displayName(): String = "User: ${this.name}"
Useful for UI code, logging, and debugging.
Validation helpers
fun MyModel.hasValidName(): Boolean = this.name.isNotBlank()
Useful before saving data or sending API requests.
Conversion helpers
fun MyModel.toDto(): MyDto = MyDto(this.name)
Useful when converting between database objects, API models, and UI models.
Collection convenience
fun List<MyModel>.names(): List<String> = this.map { it.name }
Real Codebase Usage
In real projects, developers often use extension functions as readable helper APIs around existing classes.
Common patterns
Validation helpers
fun MyModel.requireName() {
require(this.name.isNotBlank()) { "Name must not be blank" }
}
This keeps validation logic close to the type it works with.
Mapping and transformation
fun MyModel.toApiModel(): ApiModel {
return ApiModel(name = this.name)
}
This is very common in layered applications.
Guard-style helpers
fun MyModel.isReady(): Boolean = this.name.isNotBlank()
Used before running business logic.
Null-safe utility extensions
fun MyModel?.orDefaultName: String = ?.name ?:
Common Mistakes
1. Expecting the extension to become a real Java method
Broken expectation:
MyModel model = new MyModel();
model.bar(); // Error
Why it fails:
bar()is not actually added toMyModel- Java only sees real members of the class
Correct usage:
int result = ExtensionsKt.bar(model);
2. Forgetting the generated class name
Beginners often try to import the package instead of the generated class.
Correct form usually depends on the Kotlin file name.
If the file is Extensions.kt, use:
import com.test.extensions.ExtensionsKt;
Then call:
ExtensionsKt.bar(model);
3. Confusing top-level functions and extension functions
These are both compiled as static methods, but extension functions take the receiver as a parameter.
Comparisons
| Concept | Kotlin Call Style | Java Call Style | Is it a real member of the class? |
|---|---|---|---|
| Member function | model.realMethod() | model.realMethod() | Yes |
| Extension function | model.bar() | ExtensionsKt.bar(model) | No |
| Top-level function | bar() | ExtensionsKt.bar() | No |
| Static Java utility method | Utils.bar(model) | Utils.bar(model) | No |
Cheat Sheet
Quick reference
Declare an extension function
fun MyModel.bar(): Int = this.name.length
Call it in Kotlin
val result = model.bar()
Call it in Java
If the file is Extensions.kt:
int result = ExtensionsKt.bar(model);
Important rule
Extension functions are not real class methods. They are compiled as static functions.
Generated class name
Usually:
Extensions.kt->ExtensionsKtStrings.kt->StringsKt
Customize Java class name
()
FAQ
Can Java call Kotlin extension functions?
Yes. Java can call them as static methods on the generated class for the Kotlin file.
Why does model.bar() not work in Java?
Because bar() is not actually added to the MyModel class. It is compiled as a static helper function.
What class name should Java import?
Usually the Kotlin file name plus Kt, such as ExtensionsKt for Extensions.kt.
Can I make the generated Java class name nicer?
Yes. Use @file:JvmName("DesiredName") at the top of the Kotlin file.
Are extension functions the same as Java static utility methods?
Under the hood, they are very similar. The main difference is that Kotlin lets you call them with instance-like syntax.
Do extension functions override class methods?
No. Real member methods always take priority over extensions.
Can extension functions access private fields of the class?
No. They only have access to public or otherwise visible members.
Should I use extensions in a Java-heavy project?
You can, but if Java is the main consumer, regular utility methods may be easier for the team to read and discover.
Mini Project
Description
Create a small Kotlin utility file with extension functions for a Java model class, then call those functions correctly from Java. This project demonstrates the key idea that extension functions improve Kotlin syntax but are still static methods from Java's point of view.
Goal
Build and use Kotlin extension functions on a Java class, then call them from Java with the correct generated helper class.
Requirements
- Create a Java class named
MyModelwith anamefield and getter/setter. - Create a Kotlin file containing at least two extension functions for
MyModel. - Call both extension functions from Java using the generated class name or a custom
@file:JvmName. - Print the results from Java to verify everything works.
Keep learning
Related questions
Android AlarmManager Example: Scheduling Tasks with AlarmManager
Learn how to use Android AlarmManager to schedule tasks, set alarms, and handle broadcasts with a simple beginner example.
Android Foreground Service Notification Channels in Kotlin
Learn why startForeground fails on Android 8.1 and how to create a valid notification channel for foreground services in Kotlin.
Can You Extend a Data Class in Kotlin? Inheritance, Limits, and Better Alternatives
Learn why Kotlin data classes cannot be extended, what causes the component function clash, and which alternatives to use instead.