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

    На этом шаге мы рассмотрим особенности использования атрибутов класса.

    Проектируя 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
А в Java обращение к 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. Результат работы приложения

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




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