Question

How to Convert Kotlin to Java Source Files

kotlinjavacode-conversion

Question

I have a Kotlin source file, but I want to translate it into Java.

How can I convert Kotlin source code to a Java source file?

Short Answer

By the end of this page, you will understand an important distinction: Kotlin code can be compiled to JVM bytecode and used from Java, but there is no official built-in tool that reliably converts arbitrary Kotlin source code back into clean Java source code. You will also learn the practical alternatives developers use, when manual rewriting is necessary, and how Kotlin-to-Java interoperability works in real projects.

Concept

Kotlin and Java both run on the JVM, but they are different programming languages.

That means:

  • Kotlin source code (.kt) is written using Kotlin syntax and language features.
  • Java source code (.java) is written using Java syntax and Java language rules.
  • Both can be compiled into JVM bytecode (.class files).

The key idea

You usually cannot directly and cleanly convert Kotlin source into Java source automatically.

Why?

Because Kotlin has language features that do not map neatly back to Java source, such as:

  • null safety
  • data classes
  • extension functions
  • properties
  • top-level functions
  • coroutines
  • default arguments
  • object declarations
  • smart casts

When Kotlin is compiled, those features become JVM bytecode. Java can call that bytecode, but the original high-level Kotlin structure is often lost or transformed.

What is possible

There are a few practical options:

  1. Rewrite the Kotlin file manually in Java
    This is the most reliable way if you truly need .java source.

  2. Compile Kotlin and use it from Java
    In many projects, you do not need conversion at all. Java and Kotlin interoperate well on the JVM.

  3. Decompile compiled Kotlin bytecode to Java-like code
    IntelliJ IDEA can show Java code generated from compiled Kotlin classes. This is useful for learning or debugging, but it is not the same as a clean source conversion tool.

Why this matters

In real programming, developers often ask for conversion because they:

  • need to integrate with an older Java codebase
  • want to understand Kotlin code in a familiar language
  • must migrate codebases between languages
  • need Java-compatible APIs

The important lesson is that interoperability is usually better than conversion. If your goal is simply to use Kotlin code in a Java project, you often do not need a Java source file at all.

Mental Model

Think of Kotlin and Java like two spoken languages that can both be translated into the same machine-readable format.

  • Kotlin = one human language
  • Java = another human language
  • JVM bytecode = the shared machine language

A Kotlin file is like a document written in Spanish, and a Java file is like one written in English. Both can be translated into a universal code the computer understands.

But once the document is translated into that universal code, converting it back into natural, readable English is not always perfect. You may get something understandable, but not elegant or identical to what a human would write.

So:

  • Compile Kotlin when you want the program to run
  • Use from Java when you want interoperability
  • Rewrite manually when you need maintainable Java source
Take Quiz

Syntax and Examples

Kotlin and Java side by side

Here is a simple Kotlin class:

class User(val name: String, var age: Int) {
    fun isAdult(): Boolean {
        return age >= 18
    }
}

A manual Java version might look like this:

public class User {
    private final String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public boolean isAdult() {
        return age >= 18;
    }
}

What changed?

Kotlin lets you declare constructor parameters as properties directly:

class User(val name: String, var age: Int)

In Java, you must usually write:

  • fields
  • constructor
  • getters
  • setters if needed

Example of interoperability instead of conversion

Kotlin file:

class GreetingService {
    fun greet(name: String): String {
        return "Hello, $name"
    }
}

Java code calling the Kotlin class:

public class Main {
    public static void main(String[] args) {
        GreetingService service = new GreetingService();
        String message = service.greet("Sam");
        System.out.println(message);
    }
}

This is often the best solution: keep the Kotlin file as Kotlin and call it from Java.

Top-level Kotlin functions

Kotlin supports top-level functions:

fun add(a: Int, b: Int): Int {
    return a + b
}

Java cannot declare top-level functions. After compilation, Java usually accesses them through a generated class:

int result = ExampleKt.add(2, 3);

The exact generated class name usually depends on the Kotlin file name.

Step by Step Execution

Consider this Kotlin file:

fun add(a: Int, b: Int): Int {
    return a + b
}

And Java usage:

public class Main {
    public static void main(String[] args) {
        int result = MathUtilsKt.add(4, 5);
        System.out.println(result);
    }
}

Step by step

  1. The Kotlin file is compiled.
  2. The top-level function add is placed into a generated JVM class.
  3. If the file was named MathUtils.kt, Java typically sees a class named MathUtilsKt.
  4. Java calls the generated static method add(4, 5).
  5. Kotlin returns 9.
  6. Java prints 9.

Why this matters

This shows that Java does not need the Kotlin file to be rewritten as Java source. It only needs the compiled Kotlin class available on the classpath.

Another trace with a class

Kotlin:

class Counter {
    var count = 0

    fun increment() {
        count++
    }
}

Java:

public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter();
        counter.increment();
        System.out.println(counter.getCount());
    }
}

Execution flow

  1. Java creates a Counter object.
  2. count starts at 0.
  3. Java calls increment().
  4. Kotlin increases count to 1.
  5. Java calls the generated getter getCount().
  6. The program prints 1.

Kotlin properties are exposed to Java through getter and setter methods.

Real World Use Cases

1. Mixed Java and Kotlin codebases

A team may gradually adopt Kotlin in an existing Java application. Instead of converting everything, they keep both languages in the same project.

2. Android development

Android projects often contain both Java and Kotlin files. Java code can call Kotlin classes, and Kotlin code can call Java classes.

3. Library migration

A library may be rewritten partly in Kotlin, while still exposing APIs that Java consumers can use.

4. Learning and debugging

Developers sometimes inspect decompiled Java output from Kotlin classes to understand how Kotlin features are represented on the JVM.

5. Legacy systems

If a company requires Java-only source for maintenance or policy reasons, developers may manually rewrite Kotlin modules into Java.

Take Quiz

Real Codebase Usage

In real projects, developers usually avoid full source conversion and use one of these patterns instead:

Keep Kotlin implementation, expose Java-friendly APIs

Common techniques:

  • avoid overly Kotlin-specific public APIs when Java callers are expected
  • use simple method signatures
  • add overloads where needed
  • use annotations such as @JvmStatic, @JvmOverloads, or @JvmField when appropriate

Example:

class Logger {
    @JvmOverloads
    fun log(message: String, level: String = "INFO") {
        println("[$level] $message")
    }
}

Java can then call easier overloads.

Use guard clauses and validation normally

Kotlin code can validate inputs even when called from Java:

fun divide(a: Int, b: Int): Int {
    require(b != 0) { "b must not be zero" }
    return a / b
}

Java callers can still use it, and exceptions behave normally.

Manual migration for important modules

If a team must move Kotlin code to Java, they usually:

  • start with small utility classes
  • rewrite tests first or keep tests unchanged
  • manually convert data models and services
  • verify public API compatibility

Decompiled output as a reference, not final code

A developer may compile Kotlin, inspect decompiled Java, then write a cleaner Java version by hand. This is common during migration.

Common Mistakes

Assuming there is a perfect Kotlin-to-Java converter

There is no standard official tool that takes any Kotlin source file and produces clean, maintainable Java source.

Confusing decompiled Java with original source

Decompiled code may be:

  • verbose
  • hard to read
  • full of generated helper calls
  • different from human-written Java

Expecting all Kotlin features to map directly to Java

For example, this Kotlin code is compact:

data class User(val name: String, val age: Int)

A Java version needs much more code unless you use records or generation tools.

Forgetting Java interop already exists

Broken assumption:

// I must convert this Kotlin file before Java can use it.

Correct idea:

// Java can often call compiled Kotlin classes directly.

Ignoring nullability differences

Kotlin tracks nullability more explicitly than Java.

Kotlin:

fun printName(name: String) {
    println(name)
}

Java can still pass problematic values in some cases if null contracts are not respected carefully.

Relying on generated names without checking

Top-level functions and properties may be compiled into generated class names based on file names. Beginners often guess the wrong name.

Always verify the compiled output or use IDE support.

Comparisons

ApproachWhat it doesBest whenDownsides
Manual rewrite to JavaRecreates the Kotlin logic as real Java sourceYou truly need maintainable .java filesTakes time and effort
Compile Kotlin and call from JavaUses Kotlin directly in a Java projectYou only need interoperabilityRequires Kotlin in the build
Decompile Kotlin bytecode to JavaProduces Java-like code from compiled classesLearning, inspection, migration assistanceOutput may be ugly or incomplete as source

Kotlin source vs Java source

AspectKotlinJava
Syntax verbosityUsually shorterUsually more explicit
Null safetyBuilt into the type systemMore manual
PropertiesFirst-class language featureUsually getters/setters
Top-level functionsSupportedNot supported directly
Data classesBuilt inMore manual code

Conversion vs interoperability

GoalBetter choice
Run Kotlin code in a Java projectInteroperability
Understand generated JVM behaviorDecompile compiled classes
Produce clean Java source for long-term maintenanceManual rewrite
Take Quiz

Cheat Sheet

Quick facts

  • Kotlin and Java are different source languages.
  • Both compile to JVM bytecode.
  • Java can usually call compiled Kotlin code directly.
  • There is no standard clean one-click Kotlin-to-Java source converter.
  • Decompiled Java is useful for inspection, not ideal as final source.

Common options

Need Java source?        -> Rewrite manually
Need Java compatibility? -> Call Kotlin from Java
Need to inspect output?  -> Decompile compiled classes

Kotlin-to-Java interop reminders

  • Kotlin properties appear as getters/setters in Java.
  • Top-level Kotlin functions are exposed through generated classes.
  • Default arguments may need @JvmOverloads for nicer Java calls.
  • Nullability is safer in Kotlin than in plain Java.

Example

Kotlin:

class Person(val name: String)

Java usage:

Person p = new Person("Ava");
System.out.println(p.getName());

Rule of thumb

If your goal is just to use the code, do not convert it.
If your goal is to maintain Java source, rewrite it cleanly in Java.

FAQ

Can IntelliJ convert Kotlin to Java automatically?

Not as a full official source conversion feature for arbitrary Kotlin files. IntelliJ can decompile compiled classes to Java-like code, which may help you rewrite it manually.

Can Java call Kotlin code without converting it?

Yes. If the Kotlin code is compiled and included in the project, Java can usually call it directly.

Is decompiled Java the same as original source code?

No. Decompiled Java is reconstructed from bytecode, so it may be verbose or different from what a developer would write.

Why is Kotlin harder to convert back to Java source?

Because Kotlin has features that do not map neatly to Java syntax, such as data classes, extension functions, properties, and coroutines.

What is the best way to migrate Kotlin to Java?

Usually: manually rewrite the code, keep tests, compare behavior, and use decompiled output only as a reference.

Do I need Java source files to use Kotlin in a Java project?

No. In most cases, compiled Kotlin classes are enough.

Can all Kotlin code be expressed in Java?

Most behavior can be reproduced, but the Java version may be more verbose or require different patterns.

Take Quiz

Mini Project

Description

Create a tiny mixed-language JVM project where Kotlin code is used directly from Java. This demonstrates the practical alternative to source conversion: interoperability. You will define a Kotlin utility and call it from Java without rewriting the Kotlin file.

Goal

Build a small example where Java successfully calls Kotlin code and prints the result.

Requirements

  • Create one Kotlin source file with a class or top-level function.
  • Create one Java source file that calls the Kotlin code.
  • Compile or run them in the same JVM project.
  • Print at least one result from the Kotlin code in Java.
Take Quiz

Keep learning

Related questions

View more