На этом шаге мы рассмотрим проблемы соответствия типов 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 дает вам мощь объектов, когда нужно, и сохраняет производительность примитивов, когда возможно.
На следующем шаге мы рассмотрим методы свойств и совместимость.