На этом шаге мы рассмотрим взаимодествие со статическими значениями.
Вы также можете использовать @JvmField для выражения статических значений во вспомогательных объектах. Мы уже говорили о том, что вспомогательные объекты объявляются внутри класса и инициализируются, когда инициализируется вмещающий класс или когда происходит обращение к их свойствам или функциям. Добавим вспомогательный объект с одним значением MAX_SPELL_COUNT в Spellbook.
. . . . . 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") companion object { val MAX_SPELL_COUNT = 10 } }
Рис.1. Добавление вспомогательного объекта в Spellbook (Hero.kt)
Теперь попробуем обратиться к MAX_SPELL_COUNT из метода main() в Jhava, используя синтаксис Java для доступа к статическим значениям.
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); } System.out.println("Max spell count: " + Spellbook.MAX_SPELL_COUNT); } @NotNull public String utterGreeting() { return greeting; } . . . . . }
Рис.2. Обращение к статическому значению в Java (Jhava.java)
Код не компилируется. Почему? Потому что для обращения к членам вспомогательного объекта из Java необходимо сначала получить сам объект, а затем вызвать метод чтения свойства:
System.out.println("Max spell count: " + Spellbook.Companion.getMAX_SPELL_COUNT());
. . . . . 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") companion object { @JvmField val MAX_SPELL_COUNT = 10 } }
Рис.3. Добавление аннотации @JvmField к члену вспомогательного объекта (Hero.kt)
После добавления аннотации код Jhava.java скомпилируется, и вы сможете обратиться к MAX_SPELL_COUNT как к любому другому статическому значению. Запустите Jhava.kt и убедитесь, что максимальное количество заклинаний выводится в консоль.
Рис.4. Результат работы приложения
Несмотря на то что Kotlin и Java обрабатывают поля по-разному, @JvmField позволяет открыть поля и обеспечить эквивалентный способ доступа к вашим структурам из Java.
Функции, объявленные во вспомогательных объектах, имеют похожие проблемы при обращении к ним из Java, - к ним надо обращаться через ссылку на вспомогательный объект. Аннотация @JvmStatic действует подобно @JvmField, позволяя получить прямой доступ, к функциям, объявленным во вспомогательном объекте. Объявите функцию во вспомогательном объекте класса Spellbook с именем getSpellbookGreeting(). Функция getSpellbookGreeting() возвращает функцию, которая будет вызвана при вызове с getSpellbookGreeting().
. . . . . class Spellbook { val spells = listOf("Magic Ms. L", "Lay on Hans") companion object { @JvmField val MAX_SPELL_COUNT = 10 @JvmStatic fun getSpellbookGreeting() = println("I am the Great Grimoire!") } }
Рис.5. Применение @JvmStatic к функции (Hero.kt)
Теперь добавьте вызов getSpellbookGreeting() в Jhava.java.
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); } System.out.println("Max spell count: " + Spellbook.MAX_SPELL_COUNT); Spellbook.getSpellbookGreeting(); } @NotNull public String utterGreeting() { return greeting; } . . . . . }
Рис.6. Вызов статического метода в Java (Jhava.java)
Запустите Jhava.java и убедитесь, что книга заклинаний приветствует вас.
Рис.7. Результат работы приложения
Несмотря на отсутствие статических методов в Kotlin, многие его конструкции компилируются в статические переменные и методы. Применение аннотации @JvmStatic позволит вам точнее определять, как разработчики Java должны взаимодействовать с вашим кодом.
На следующем шаге мы рассмотрим исключения и совместимость.