Шаг 235.
Основы Kotlin.
Совместимость с Java. Соответствие типов

    На этом шаге мы рассмотрим проблемы соответствия типов Kotlin и Java.

    Типы в Kotlin и Java часто прямо соответствуют друг другу. Тип String в Kotlin также остается String, когда компилируется в Java. Это значит, что String, возвращаемый методом Java, можно использовать в Kotlin, как если бы это значение было получено непосредственно в Kotlin.

    Однако есть типы, не имеющие прямых аналогов. Например, базовые типы. Как уже обсуждалось, Java представляет базовые типы данных через примитивы. Примитивы в Java - это не объекты, однако в Kotlin все типы - это объекты, включая базовые типы. Несмотря на это, компилятор Kotlin может отображать простые типы Java в наиболее простые типы в Kotlin.

    Чтобы увидеть, как происходит такое преобразование, добавьте целочисленное значение hitPoints в Jhava. Целое число представлено как объект типа Int в Kotlin и как примитив int в Java.

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class Jhava {

    public int hitPoints = 52489112;

    @NotNull
    public String utterGreeting() {
        return "BLARGH";
    }

    @Nullable
    public String determineFriendshipLevel() {
        return null;
    }
}


Рис.1. Объявление int в java (Jhava.java)

    Теперь получим ссылку на hitPoints в Hero.kt.

fun main(args: Array<String>) {
    val adversary = Jhava()
    println(adversary.utterGreeting())

    val friendshipLevel = adversary.determineFriendshipLevel()
    println(friendshipLevel?.toLowerCase() ?: "It's complicated.")

    val adversaryHitPoints: Int = adversary.hitPoints
}


Рис.2. Обращение к полю Java из Kotlin (Hero.kt)

    Несмотря на то что hitPoints объявлен в Jhava как int, у вас не возникло проблем при обращении к нему как к Int.


Мы не используем автоматическое определение типов в примере только для того, чтобы показать как происходит преобразование типов. Явные объявления типов не нужны для интеграции языков: объявление
    val adversaryHitPoints: Int = adversary.hitPoints
ничуть не хуже.

    Теперь, когда у вас есть ссылка на целое число, вы можете вызывать функции с ним. Вызовите функцию для adversaryHitPoints() и выведите результат.

fun main(args: Array<String>) {
    val adversary = Jhava()
    println(adversary.utterGreeting())

    val friendshipLevel = adversary.determineFriendshipLevel()
    println(friendshipLevel?.toLowerCase() ?: "It's complicated.")

    val adversaryHitPoints: Int = adversary.hitPoints
    println(adversaryHitPoints.dec())
}


Рис.3. Обращение к полю Java через Kotlin (Hero.kt)

    Запустите Hero.kt для вывода очков здоровья противника, уменьшенных на 1.


Рис.4. Результат работы приложения

    В Java нельзя вызывать методы для простых типов. В Kotlin целое число adversaryHitPoints - это объект типа Int, и вы можете вызывать его функции.

    В качестве еще одного примера преобразования типов выведите имя класса Java, которому принадлежит adversaryHitPoints.

fun main(args: Array<String>) {
    val adversary = Jhava()
    println(adversary.utterGreeting())

    val friendshipLevel = adversary.determineFriendshipLevel()
    println(friendshipLevel?.toLowerCase() ?: "It's complicated.")

    val adversaryHitPoints: Int = adversary.hitPoints
    println(adversaryHitPoints.dec())
    println(adversaryHitPoints.javaClass)
}
Файл с проектом можно взять здесь.


Рис.5. Имя класса поддержки Java (Hero.kt)

    Если вы запустите Hero.kt, вы увидите int в консоли.


Рис.6. Результат работы приложения

    Несмотря на то что вы можете вызвать функции типа Int для adversaryHitPoints, во время работы программы переменная является примитивом int. А теперь давайте вспомним байт-код. В нем все типы Kotlin преобразуются в их аналоги в Java. Kotlin дает вам мощь объектов, когда нужно, и сохраняет производительность примитивов, когда возможно.

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




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