Шаг 237.
Основы Kotlin.
Совместимость с Java. За пределами класса

    На этом шаге мы рассмотрим вызов Kotlin-функции из метода Java.

    Kotlin предлагает разработчикам большую гибкость в выборе формата для кода, который они пишут. Файл Kotlin может одновременно содержать и классы, и функции, и переменные на верхнем уровне файла. В Java файл может представлять только один класс. Тогда как именно функции верхнего уровня, объявленные в Kotlin, выглядят в Java?

    Расширим межвидовое общение, добавив ответ героя. В Hero.kt объявите функцию с именем makeProclamation за пределами функции main().

fun main(args: Array<String>) {
    val adversary = Jhava()

    val friendshipLevel = adversary.determineFriendshipLevel()
    println(friendshipLevel?.toLowerCase() ?: "It's complicated.")

    val adversaryHitPoints: Int = adversary.hitPoints
    println(adversaryHitPoints.dec())
    println(adversaryHitPoints.javaClass)

    adversary.greeting = "Hello, Hero."
    println(adversary.utterGreeting())
}

fun makeProclamation() = "Greetings, beast!"


Рис.1. Объявление функции высшего порядка в Kotlin (Hero.kt)

    Вам нужен способ вызвать эту функцию из Java, поэтому добавьте метод main() в Jhava. В этом методе main() выведите значение, возвращаемое makeProclamation(), обратившись к функции как к статическому методу класса HeroKt.

public class Jhava {
.   .   .   .   .
    public static void main(String[] args) {
        System.out.println(HeroKt.makeProclamation());
    }
.   .   .   .   .
}


Рис.2. Обращение к функции высшего порядка Kotlin из Java (Jhava.java)

    Функции верхнего уровня, объявленные в Kotlin, доступны и вызываются в Java как статические методы. Функция makeProclamation() объявлена в Hero.kt, поэтому компилятор Kotlin создаст класс с именем HeroKt и поместит в него эту функцию как статический метод.

    Чтобы взаимодействия между Hero.kt и Jhava.java выглядели более гладкими, можно изменить имя создаваемого класса , добавив в начало Hero.kt аннотацию @JvmName.

@file:JvmName("Hero")

fun main(args: Array<String>) {
    .   .   .   .
}

fun makeProclamation() = "Greetings, beast!"


Рис.3. Объявление имени скомпилированного класса с помощью JvmName (Hero.kt)

    Теперь в Jhava можно использовать более понятный вызов функции makeProclamation().

public class Jhava {
.   .   .   .   .
    public static void main(String[] args) {
        System.out.println(Hero.makeProclamation());
    }
.   .   .   .   .
}
Файл с проектом можно взять здесь.


Рис.4. Ссылка на переименованную функцию верхнего уровня Kotlin из Java (Jhava.java)

    Запустите Jhava.java, чтобы увидеть ответ вашего героя.


Рис.5. Результат работы приложения

    Аннотации JVM, такие как @JvmName, дают возможность прямо определять, какой код Java будет сгенерирован из исходного кода на Kotlin.

    На следующем шаге мы продолжим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг