Fading Coder

One Final Commit for the Last Sprint

Home > Tools > Content

Kotlin Top-Level Functions and Properties for Java Interoperability

Tools 1

When Kotlin files are compiled, top-level functions declared within them are converted into static methods. These methods are housed in a class named after the Kotlin file with a Kt suffix. For instance, a file named MathUtils.kt will produce a class named MathUtilsKt.

// MathUtils.kt
package com.example.utils

fun calculateProduct(x: Int, y: Int): Int {
    return x * y
}

The equivalent compiled Java bytecode looks like:

public class MathUtilsKt {
    public static int calculateProduct(int x, int y) {
        return x * y;
    }
}

Invoking Top-Level Functions from Java

To call a top-level Kotlin function from Java, use the generated class name followed by the method name.

// ClientApp.java
import com.example.utils.MathUtilsKt;

public class ClientApp {
    public static void main(String[] args) {
        int product = MathUtilsKt.calculateProduct(6, 7);
        System.out.println("Calculated product: " + product);
    }
}

Customizing the Generated Class Name with @JvmName

The @JvmName annotation modifies the name of the generated wrapper class. By placing @file:JvmName("CalculatorHelper") at the top of the Kotlin file, the compiler changes the facade class name from MathUtilsKt to CalculatorHelper.

// MathUtils.kt
@file:JvmName("CalculatorHelper")
package com.example.utils

fun calculateProduct(x: Int, y: Int): Int {
    return x * y
}

The Java implementation then imports and calls the method using the new class name:

// ClientApp.java
import com.example.utils.CalculatorHelper;

public class ClientApp {
    public static void main(String[] args) {
        int product = CalculatorHelper.calculateProduct(6, 7);
        System.out.println("Calculated product: " + product);
    }
}

Merging Multiple Files with @JvmMultifileClass

If multiple Kotlin files use @JvmName to generate the same facade class name, a compilation conflict occurs. The @JvmMultifileClass annotation resolves this by instructing the compiler to generate a single facade class containing the top-level declarations from all associated files.

// GeometryOps.kt
@file:JvmName("CalculatorHelper")
@file:JvmMultifileClass
package com.example.utils

fun calculateProduct(x: Int, y: Int): Int {
    return x * y
}
// AlgebraOps.kt
@file:JvmName("CalculatorHelper")
@file:JvmMultifileClass
package com.example.utils

fun computeSum(x: Int, y: Int): Int {
    return x + y
}

Both functions become accessible through the unified CalculatorHelper class in Java:

// ClientApp.java
import com.example.utils.CalculatorHelper;

public class ClientApp {
    public static void main(String[] args) {
        int product = CalculatorHelper.calculateProduct(6, 7);
        int sum = CalculatorHelper.computeSum(6, 7);
        System.out.println("Product: " + product + ", Sum: " + sum);
    }
}

Accessing Kotlin Constants from Java

Kotlin properties marked with the const modifier are compiled into static fields in Java. This applies to top-level properties, properties inside objects, and properties inside companion objects.

// Constants.kt
package com.example.utils

const val MAX_LIMIT = 500

object Config {
    const val THRESHOLD = 10
}

class SystemSettings {
    companion object {
        const val VERSION_CODE = 2
    }
}

These constants are accessed as standard static variables in Java:

// ClientApp.java
import com.example.utils.ConstantsKt;

public class ClientApp {
    public static void main(String[] args) {
        int limit = ConstantsKt.MAX_LIMIT;
        int threshold = Config.THRESHOLD;
        int version = SystemSettings.VERSION_CODE;
        System.out.println("Limit: " + limit + ", Threshold: " + threshold + ", Version: " + version);
    }
}

Related Articles

Efficient Usage of HTTP Client in IntelliJ IDEA

IntelliJ IDEA incorporates a versatile HTTP client tool, enabling developres to interact with RESTful services and APIs effectively with in the editor. This functionality streamlines workflows, replac...

Installing CocoaPods on macOS Catalina (10.15) Using a User-Managed Ruby

System Ruby on macOS 10.15 frequently fails to build native gems required by CocoaPods (for example, ffi), leading to errors like: ERROR: Failed to build gem native extension checking for ffi.h... no...

Resolve PhpStorm "Interpreter is not specified or invalid" on WAMP (Windows)

Symptom PhpStorm displays: "Interpreter is not specified or invalid. Press ‘Fix’ to edit your project configuration." This occurs when the IDE cannot locate a valid PHP CLI executable or when the debu...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.