How is Kotlin able to call Java 11 code using JDK 1.8?

Tags: , ,



I was playing around with a Kotlin project which has some Java 11 calls and noticed that it seems to build and run fine using Java 8.

The call in particular is to java.lang.String#isBlank(), which was introduced in Java 11.

I’m using Gradle to build and run tests. Build JDK is set to JDK 1.8 and Kotlin compile target is also 1.8:

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs += listOf("-Xjsr305=strict")
        jvmTarget = "1.8"
    }
}
gradle -v

------------------------------------------------------------
Gradle 6.6
------------------------------------------------------------

Build time:   2020-08-10 22:06:19 UTC
Revision:     d119144684a0c301aea027b79857815659e431b9

Kotlin:       1.3.72
Groovy:       2.5.12
Ant:          Apache Ant(TM) version 1.10.8 compiled on May 10 2020
JVM:          1.8.0_265 (AdoptOpenJDK 25.265-b01)
OS:           Mac OS X 10.15.6 x86_64

This is a unit test which calls Java 11 but still compiles and runs:

import org.junit.jupiter.api.Test

class BlankTest {

    @Test
    fun testBlank() {
        val s = java.lang.String("test string")
        val blank = s.isBlank()
        println("Input string blank? : $blank")
    }
}

How is this possible?

Answer

The answer is that you’re not actually using Java 11’s isBlank() method, you’re calling Kotlin’s isBlank extension function that can be applied to java.lang.String.



Source: stackoverflow