На этом шаге мы рассмотрим вызов 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.
На следующем шаге мы продолжим изучение этого вопроса.