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

    На этом шаге мы рассмотрим взаимодествие со статическими значениями.

    Вы также можете использовать @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());
Аннотация @JvmField сделает это за вас. Добавьте аннотацию @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 {
        @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 должны взаимодействовать с вашим кодом.

    На следующем шаге мы рассмотрим исключения и совместимость.




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