Interoperability tips with Kotlin for Java developers

When calling Kotlin code from Java

Default argument

If you want to handle Kotlin functions with default arguments from Java, you have to specify all the arguments. However, if you add the @JvmOverload annotation to the function, the overload method will be generated automatically.

// Kotlin
class OverloadSample {
    @JvmOverloads //Annotating will generate an overloaded method that can be called from Java
    fun test(arg1: Boolean = true, arg2: Int = 1, arg3: String = "true") : Boolean {
        return arg1 && arg2 == 1 && arg3 == "true"
    }
}

Let's implement the call code from Java.

// Java
OverloadSample os = new OverloadSample();
os.test(true, 1, "true");
os.test(true, 1);
os.test(true);

Top level functions, properties

This is a method to call a top-level Kotlin function that does not belong to a class from Java. Kotlin's top-level functions A class named source filename + Kt is generated It will be compiled into a static function of that class.

// Utility.kt
fun doSomething() {
    // Do something
}
// Java
UtilityKt.doSomething();

If you want to change the above class name source file name + Kt, use the @JvmName annotation. This annotation is described in the package.

// Utility.kt
@file: JvmName("Util")
package com.sample

fun doSomething() {
    // Do something
}
// Java
Util.doSomething();

Extension function

Extension functions, like top-level functions, are compiled as static functions of the class named source filename + Kt. When calling from Java, the object that becomes this is the first argument.

// StringUtility.kt
fun String.join(otherString: String) : String {
    return this + otherString
}
// Java
StringUtilityKt.join("Hello, ", "World!");

object class

Looking at the object class from Java, it is a class with a static field called ʻINSTANCE. To access a property or function of the object class, go through this ʻINSTANCE.

// Kotlin
object LogUtil {
    fun debug(log: String) {
        //
    }
}
// Java
LogUtil.INSTANCE.debug("completed!");

When calling Java code from Kotlin

Platform type

For example, when receiving the return value of a Java function in Kotlin code Whether the return value is nullable or not depends on @ NonNull and @ Nullable. It is judged by the annotation.

// Java
public class Sample {

    @NonNull
    String getString1() {
        return //
    }

    @Nullable
    String getString2() {
        return //
    }
}

When called with Kotlin, it looks like this:

// Kotlin
val sample = Sample()
val str1 = sample.string1 //Non-nullable type
val str2 = sample.string2 //Nullable type

However, the annotations for @NonNull and @Nullable are Please note that it is not enforceable at compile time.

Then, if you don't add annotations ...

// Java
public class Sample {
    //No annotation
    String getString3() {
        return  //
    }
}

Let's call it from Kotlin.

// Kotlin
val sample = Sample()
val str3 = sample.string3 // String!

It will be of type String!. The type with ! Is called the platform type.

Both types can handle both nullable and non-nullable types. The idea is to leave it up to the developer to decide whether it is null or not.

// Kotlin
val sample = Sample()
val str = sample.string3
val length = str.length //Treat as non-nullable type
val char = str?.get(0) //Treat as nullable type

static function, static field

There can be situations where you need a static function or field for some reason. For example ...

A companion object that can be used statically in Kotlin. If you use annotations here, it will be compiled as Java static.

// Kotlin
class Sample {
    companion object {

        @JvmField //Annotation that specifies compilation to a static field
        var TAG: String = "Sample"

        @JvmStatic //Annotation that specifies compilation to a static function
        fun tag(): String {
            return "Sample"
        }
    }
}
// Java
String tag = Sample.TAG;
tag = Sample.tag();

SAM conversion

Under certain conditions You can create a class that implements the Java interface with a lambda expression.

val executor: ThreadPoolExecutor

//Pass an object that implements Runnable as an argument of execute method
executor.execute(object: Runnable{
    override fun run() {
        //
    }
})

//It can be expressed by a lambda expression by SAM conversion!
executor.execute { 
    //
}

The conditions under which SAM conversion is enabled in Kotlin are as follows.

SAM conversion is not enabled in the interface declared in Kotlin because Kotlin has the appropriate function type

Recommended Posts

Interoperability tips with Kotlin for Java developers
Generics of Kotlin for Java developers
Getting started with Kotlin to send to Java developers
[Java] Tips for writing source
Enable OpenCV with java8. (For myself)
Java tips, tips
Java Tips
Kotlin Class part.2 to send to Java developers
Getting Started with Ruby for Java Engineers
Learn Java with "So What" [For beginners]
[For beginners] Difference between Java and Kotlin
Kotlin scope functions to send to Java developers
Introduction to kotlin for iOS developers ⑥-Kotlin creation
[Kotlin] Delete files with duplicate contents [Java]
Introduction to kotlin for iOS developers ④-Type
Memo for migration from java to kotlin
[Java] How to test for null with JUnit
Kotlin functions and lambdas to send to Java developers
Specify Java / Kotlin compile-time options for Android apps
Ask for n business days later with JAVA
For JAVA learning (2018-03-16-01)
Simple obstacle racing made with processing for Java
tips for java.nio.file.Path
Initial settings for rewriting Java projects to Kotlin
Introduction to kotlin for iOS developers ⑤-Practical XML
2017 IDE for Java
Tips for improving Jbuilder rendering time with jsonapi-serializer
Introduction to kotlin for iOS developers ③-About gradle
For Java engineers starting Kotlin from now on
Docker Container Operations with Docker-Client API for Java
Introduction to kotlin for iOS developers ①-Environment construction
Introduction to kotlin for iOS developers ②-Project creation
Tips for testing with mock for classes using @value
Java for statement
CI the architecture of Java / Kotlin applications with ArchUnit
Call a method with a Kotlin callback block from Java
Java programming exercises for newcomers unpopular with active engineers
[Java basics] Let's make a triangle with a for statement
Get Azure App Service for Java Configuration with System.getEnv ()
Generate dummy data for various tests with Faker (java)
[Java] Environment construction procedure for developing struts 1.3 with Eclipse
I want to transition screens with kotlin and java!
Try connecting to AzureCosmosDB Emulator for Docker with Java
Prepare the environment for java11 and javaFx with Ubuntu 18.4
Install java with Homebrew
[Java] for statement, while statement
Change seats with java
Install Java with Ansible
[Java] Package for management
[Java] for statement / extended for statement
Comfortable download with JAVA
Countermeasures for Java OutOfMemoryError
Switch java with direnv
[Java, Kotlin] Type Variance
NLP for Java (NLP4J) (2)
(Memo) Java for statement
Download Java with Ansible
Let's scrape with Java! !!
Build Java with Wercker
Endian conversion with JAVA
Store in Java 2D map and turn with for statement