На этом шаге мы рассмотрим особенности использования атрибутов класса.
Проектируя API, который можно использовать из Java, не забывайте применять аннотацию @JvmOverloads, чтобы сделать свой API для разработчиков на Java таким же гибким, как для разработчиков на Kotlin.
Существуют еще две JVM-аннотации для использования в коде на Kotlin, который будет взаимодействовать с кодом Java, и обе они имеют отношение к классам. Hero.kt пока не имеет реализации класса, поэтому добавим новый класс с именем Spellbook. Добавьте в Spellbook свойство spells - список строк с названиями заклинаний.
. . . . . fun makeProclamation() = "Greetings, beast!" fun handOverFood(leftHand: String = "berries", rightHand: String = "beef") { println("Mmmm... you hand over some delicious $leftHand and $rightHand.") } class Spellbook { val spells = listOf("Magic Ms. L", "Lay on Hans") }
Рис.1. Объявление класса Spellbook (Hero.kt)
Как вы уже знаете, Java и Kotlin представляют переменные класса совершенно по-разному: Java использует поля с методами чтения и записи, а Kotlin предлагает свойства со вспомогательными полями. Как результат, в Java вы можете обращаться к полям напрямую, а в Kotlin путь к полю лежит через методы доступа, даже при том что синтаксис обращения может выглядеть одинаково.
Поэтому ссылка на spells, свойство Spellbook, в Kotlin будет выглядеть так:
val spellbook = Spellbook() val spells = spellbook.spells
Spellbook spellbook = new Spellbook(); List<String> spells = spellbook.getSpells();
В Java не получится обойтись без вызова getSpells() из-за отсутствия прямого доступа к полю spells. Но можно применить аннотацию @JvmField к свойству Kotlin, чтобы разрешить пользователям Java использовать поле и избавить их от необходимости вызывать метод чтения. Добавьте @JvmField в spells, чтобы открыть прямой доступ к spells для Jhava.
. . . . . fun makeProclamation() = "Greetings, beast!" fun handOverFood(leftHand: String = "berries", rightHand: String = "beef") { println("Mmmm... you hand over some delicious $leftHand and $rightHand.") } class Spellbook { @JvmField val spells = listOf("Magic Ms. L", "Lay on Hans") }
Рис.2. Применение аннотации @JvmField (Hero.kt)
Теперь в методе main() Jhava.java вы можете напрямую обратиться к spells и вывести каждое заклинание.
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public class Jhava { private int hitPoints = 52489112; private String greeting = "BLARGH"; public static void main(String[] args) { System.out.println(Hero.makeProclamation()); System.out.println("Spells:"); Spellbook spellbook = new Spellbook(); for (String spell : spellbook.spells) { System.out.println(spell); } } @NotNull public String utterGreeting() { return greeting; } . . . . . }
Рис.3. Обращение к полю Kotlin напрямую из Java (Jhava.java)
Запустите Jhava.java и убедитесь, что все заклинания из книги заклинаний выводятся в консоль.
Рис.4. Результат работы приложения
На следующем шаге мы закончим изучение этого вопроса.