Взаимодействие между Java и Kotlin

Узнайте о совместимости между Java и Kotlin в этой статье Абида Хана, разработчика приложений и инженера-тестировщика с более чем 10-летним опытом, и Игоря Кучеренко, разработчика Android в Techery, компании-разработчике программного обеспечения, которая использует Kotlin в качестве основного языка для Android. разработка.

Совместимость

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

Вы начнете с вызова статических переменных и функций Java в Kotlin, затем перейдете к коллекциям Java и изучите несколько примеров вызова классов Java в Kotlin. Затем вы увидите, как обрабатывать резервные слова Kotlin и использовать написанный Kotlin код на Java с переменными, функциями, функциями расширения и классом Kotlin. Вы также увидите замену имен файлов и функций Kotlin с помощью предоставленной Kotlin аннотации JVM. Наконец, вы быстро узнаете, как вызывать класс объектов Kotlin в Java.

Технические требования

Кроме IntelliJ IDEA, эта статья не требует каких-либо специальных установок. Код для этой статьи можно скачать из репозитория GitHub: https://github.com/PacktPublishing/Hands-On-Object-Oriented-Programming-with-Kotlin/tree/master/src/main/kotlin/Chapter08.

Вызов Java-кода в Котлине

В этом разделе вы узнаете, как использовать код Java в файле Kotlin. Для простоты начните с создания пакета и добавления файлов Java и Kotlin в одном месте, поскольку вы знаете, что Kotlin позволяет хранить файлы Java и Kotlin в одном проекте. Итак, у вас есть два класса Java с именами CallJava и Shape, и в той же папке у вас есть один файл Kotlin с именем FromKotlin:

1.png

Начните со статической переменной и функции Java.

Вызов статических переменных и функций

Откройте файл CallJava и добавьте одно сообщение статической переменной:
public static String message = «Привет с Java»;
Включите один статический метод add, который добавляет две переменные и выводит сообщение на экран:

public static void add(int i, int j){
    System.out.println(i + " + " + j + "=" + (i + j));
}

Вызов статической функции или переменной из Java в Kotlin очень прост. Для этого используйте имя файла Java в качестве ссылки и вызовите требуемую функцию или переменную. Посмотрите на следующий пример Kotlin для вызова статической переменной Java:

fun callStaticFromJava() {
    var message = CallJava.message
    println("Java Message : ${message}")

    CallJava.add(4,5)
}

Чтобы вызвать статическую переменную, используйте имя класса Java в качестве ссылки вместе с именем переменной CallJava.message. Это значение можно присвоить локальной переменной и использовать как обычную переменную Kotlin. Точно так же вызовите статическую функцию Java, используя имя класса в качестве ссылки вместе с именем функции. Вызовите метод add из Java с помощью CallJava.add(4,5) и передайте две целочисленные переменные в качестве параметров.

Вызов коллекции Java в Котлине
Создайте метод в Java, который возвращает список целых чисел:

public static ArrayList<Integer> getIntList(){

    ArrayList<Integer> integers = new ArrayList<>();
    integers.add(1);integers.add(2);integers.add(3);

return integers;
}

getIntList возвращает массив, содержащий три элемента. Вызовите эту функцию в Kotlin, чтобы получить доступ к списку и добавить в него дополнительные элементы:

var list = CallJava.getIntList()
//var list: ArrayList<Int> = CallJava.getIntList()

list.add(4)
for (element in list) {
println("Element $element")
}

CallJava.getIntList() возвращает ArrayList, который может быть присвоен типу списка переменных. Вы можете явно объявить тип списка, используя имя ArrayList:

var list: ArrayList<Int> = CallJava.getIntList()

Кроме того, вы можете напрямую присвоить список переменной, и Kotlin сам определит тип списка:

var list = CallJava.getIntList()

Вы можете рассматривать это как обычный неизменяемый список и добавлять или удалять элементы.

Резервные слова в Котлине
Есть ряд ключевых слов, которые используются Kotlin для внутренних целей, и их нельзя использовать в качестве имен переменных и объявлений функций. Вот некоторые резервные слова:

in, is, as, object, val, var, for, fun, interface, when 

Есть зарезервированные слова, которые Kotlin зарезервировал для себя, но когда дело доходит до Java, большинство зарезервированных ключевых слов Kotlin являются обычными переменными для Java. См. следующий пример:

public static void is(){
    System.out.println("is is a reserved keyword in Kotlin :-) ");

}

public static void var(){
    System.out.println("var is a reserved keyword in Kotlin :-) ");
} 

var и is — обычные ключевые слова для Java, но не для Kotlin. Если вам нужно вызвать функцию с зарезервированными словами Kotlin, вам нужно использовать оператор обратной кавычки. См. следующий пример Котлина:

CallJava.`is`()
CallJava.`var`()

Используйте оператор обратной кавычки («) для вызова функций Java, имена которых являются зарезервированными ключевыми словами для Kotlin. Вот еще несколько примеров, чтобы увидеть, как использовать функции Java, имена которых содержат зарезервированные ключевые слова Kotlin.

Напишите на Kotlin функцию, которая принимает ввод от пользователя и отображает сообщение на экране. Kotlin использует предоставленный Java класс Scanner для ввода данных с клавиатуры следующим образом:

fun inputFromKeyboard() {
println("Enter Your name .... ")
val scanner = Scanner(System.`in`)
println("My name is ${scanner.nextLine()}")
}

Класс Scanner использует System.in в качестве входного потока для сканирования ввода. Как видите, in — это зарезервированное ключевое слово, но вы можете использовать его с помощью оператора обратных кавычек. Точно так же вы можете использовать все зарезервированные ключевые слова в качестве имени функции или переменной следующим образом:

fun `in`(){
println("I am in function")
}

fun `as`(){
println("I am as function")
}

fun `object`(){
println("I am object function")
}  

var `var` = "Reserved keyword var"
var `object` = "Reserved keyword object"

Классы Java в Котлине

Теперь изучите, как создать объект класса Java в Kotlin. Для этого создайте файл Shape.java с тремя свойствами: высота, ширина и имя с геттерами и сеттерами:

public class Shape {

private int width;
private int height;
public static final double PI = 3.1415;
private final String name;

public Shape(int width, int height, String name) {
this.width = width;
this.height = height;
this.name = name;
    }
public final int getHeight() {
return this.height;
    }

public final void setHeight(int value) {
this.height = value;
    }

public final String getName() {
return this.name;
    }
public final void shapeMessage() {
        System.out.println("Hi i am " + this.name + ", how are you doing");
    }
}

Создание экземпляра класса Java в Kotlin аналогично созданию экземпляра класса Kotlin. См. следующий пример:

val shape = Shape(5,10,"Square")

shape — это экземпляр класса Shape, который может обращаться к функциям и обновлять свойства класса:

shape.shapeMessage()
shape.height = 10
println("name ${shape.name} height = ${shape.height}")

Вызов кода Kotlin в Java
Вызов кода Kotlin в Java аналогичен вызову кода Java в Kotlin, за исключением нескольких вещей, которые необходимо учитывать перед началом. Начните с вызова функции. Для этого создайте новую папку и добавьте файлы Java и Kotlin в одно место:

2.png

Вызов функции Котлина

Теперь создайте две функции в Kotlin, add и addAndReturn. Функция add принимает две целочисленные переменные, складывает их и выводит на экран, а addAndReturn складывает два значения и возвращает результат:

fun add(a : Int, b : Int) {
println("Result of $a + $b is ${a+b}")
}


fun addAndReturn(i: Int, j: Int): Int {
return i + j
}

Вы можете вызывать каждую функцию Kotlin, используя имя файла в качестве ссылки. CallKotlin.kt — это файл, содержащий функцию Kotlin. При вызове функции Kotlin в файле Java важно помнить, что вы должны добавить ключевое слово kt с именем файла Kotlin, чтобы вызвать нужную функцию. Например, вы можете вызвать функцию добавления с помощью CallKotlinKt.add. См. следующий пример файла Java:

public static void main(String args[]) {

    CallKotlinKt.add(5,5);

int result = CallKotlinKt.addAndReturn(5,5);
    System.out.print("From Kotlin: result = " + result);

}

Выполните этот код, и он отобразит следующий вывод:

Result of 5 + 5 is 10
From Kotlin: result = 10

Функции расширения

Также можно вызвать функцию расширения Kotlin в Java. В Kotlin создайте функцию расширения, которая принимает один параметр, умножает значение на 2 и возвращает результат. См. следующую функцию расширения Kotlin:

fun Int.doubleTheValue() = this * 2

Создайте эту функцию расширения в классе Kotlin и вызовите эту функцию в основную функцию Java, используя функцию CallKotlinKt.doubleTheValue. См. следующий пример:

public static void main(String args[]) {
int i = 5;
int result = CallKotlinKt.doubleTheValue(i);
    System.out.print("Kotlin's Extension function, Multiply "+ i +" with 2 = "+ result);
}

В результате вывод будет таким, как ожидалось:

Kotlin's Extension function, Multiply 5 with 2 = 10

Функции с изменяемыми коллекциями

Создайте изменяемый список в функции getMutableList и верните список следующим образом:

fun getMutableList() : MutableList<Int> {
val list = mutableListOf(1,2,3,4,5)
return list
}

Создайте переменную listFromKotlin в Java и назначьте этой переменной список с помощью функции CallKotlinKt.getMutableList из Kotlin. См. следующий пример:

public static void main(String args[]) {

    System.out.print("Kotlin mutable list");
//List<int> listFromKotlin = KotlinToJavaKt.mutableList();

List<Integer> listFromKotlin = CallKotlinKt.getMutableList();
    listFromKotlin.add(6);
for (int i = 0; i < listFromKotlin.size(); i++) {
        System.out.println("Element " +  listFromKotlin.get(i));
    } 
}

Обратите внимание, что Kotlin не знаком с примитивными типами данных. В результате вы должны предоставить список классов Integer:

//List<int> listFromKotlin = KotlinToJavaKt.mutableList(); // list of int
List<Integer> listFromKotlin = CallKotlinKt.getMutableList(); // List of Integers

Функции с неизменяемыми коллекциями

Теперь посмотрим, как получить неизменяемый список из функции Kotlin в Java. Создайте неизменяемый список в функции getImmutableList и верните список:

fun getImmutableList() : List<Int> {
val list = listOf(1,2,3,4,5)
return list
}

Получите список Kotlin, вызвав функцию getImmutableList и отобразив элементы списка. См. следующий пример:

public static void main(String args[]) {
    System.out.println("Kotlin immutable list");

    List<Integer> listFromKotlin = CallKotlinKt.getImmutableList();

for (int i = 0; i < listFromKotlin.size(); i++) {
        System.out.println("Element " +  listFromKotlin.get(i));
    }
}

Поскольку вы знаете, что неизменяемый список нельзя обновить, вы можете читать список, но не можете добавлять или обновлять элементы. После вызова неизменяемого списка в Java программист обязан проверить тип списка перед его обновлением, поскольку компилятор Java не может обнаружить ошибку во время компиляции. Если вы попытаетесь добавить элемент в неизменяемый список Kotlin, вы получите следующий результат:

List<Integer> listFromKotlin = KotlinToJavaKt.getImmutableList();
listFromKotlin.add(6);

Это показывает, что Java выдает исключение java.lang.UnsupportedOperationException во время выполнения, и приложение аварийно завершает работу.

Функции с аннотацией JVM

Вы можете вызвать функцию Kotlin в Java, используя имя файла в качестве ссылки. Вам также необходимо добавить ключевое слово kt с именем файла; например, KotlinToJavakt. Однако Kotlin позволяет назначать разные имена вашим файлам и именам функций. Создайте новый класс с именем CallKotlinUtil.kt и добавьте следующий код:

@file:JvmName("KotlinUtil")
package Chapter08.CallKotlinFromJava

fun addition (a: Int, b : Int){

println("Result of $a + $b is ${a+b}")

}

Используйте аннотацию @file:JvmName(«KotlinUtil») в начале файла. Теперь вы можете вызывать функцию добавления, используя KotlinUtil.addition вместо CallKotlinUtilkt.addition. См. следующий пример:

public static void main(String args[]) {
    KotlinUtil.addition(4,4);
}

Это гораздо лучший и более чистый подход. Теперь вы можете указать имя файла Kotlin для класса Java, чтобы использовать его в качестве ссылки. Kotlin также позволяет указать имя функции Kotlin для Java. Создайте дополнительную функцию в файле Kotlin и добавьте аннотацию @JvmName с новым именем функции, как показано ниже:

@file:JvmName("KotlinUtil")
package CallKotlinFromJavaPackage

@JvmName ("addDouble")
fun addition (a: Double, b : Double){
println("Result of $a + $b is ${a+b}")
}

Теперь вы можете вызвать функцию сложения, используя addDouble. См. следующий пример:

public static void main(String args[]) {
    KotlinUtil.addDouble(5.0, 5.0);
}

Вызов класса Kotlin

В этом разделе вы увидите, как вызывать класс Kotlin в Java. Создайте класс Shape в Kotlin с тремя свойствами: высотой, шириной и площадью, а также двумя функциями, shapeMessage и draw:

class Shape(var width : Int, var height : Int , val shape: String) {

var area : Int = 0
fun shapeMessage(){
println("Hi i am $shape, how are you doing")
    }
fun draw() {
println("$shape is drawn")
    }

fun calculateArea(): Int {
area = width * height
return area
}
}

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

class FromKotlinClass {

public void callShpaeInstance() 
    {
        Shape shape = new Shape(5,5,"Square");

        shape.shapeMessage();
        shape.setHeight(10);
        System.out.println(shape.getShape() + " width " + shape.getWidth());
        System.out.println(shape.getShape() + " height " + shape.getHeight());
        System.out.println(shape.getShape() + " area " + shape.calculateArea());

        shape.draw();
    }
}

Создайте экземпляр формы, добавив параметры конструктора. Вы можете использовать экземпляр формы для доступа ко всем свойствам класса с помощью методов получения и установки. Вы также можете вызывать shapeMessage или рисовать функции класса Shape, используя экземпляр shape.

Вызов одноэлементного класса Kotlin

Вы также можете вызвать одноэлементный класс Kotlin в Java. Создайте одноэлементный класс в Kotlin, используя ключевое слово object:

object Singleton {
fun happy() { 
println("I am Happy")
    }
}

Кроме того, вызовите класс Singleton и функцию happy в Java, используя ключевое слово INSTANCE:

public static void main(String args[]) {
    Singleton.INSTANCE.happy();
}

Обратите внимание, что вам не нужно использовать имя файла Kotlin в качестве ссылки, достаточно имени класса объекта Singleton. Вы также можете пропустить ключевое слово INSTANCE. Добавьте аннотацию @JvmStatic в начало сигнатуры функции:

object Singleton {

fun happy() {
println("I am Happy")
    }

@JvmStatic fun excited() {
println("I am very Excited")
    }
}

Как только это будет сделано, вызовите возбужденную функцию напрямую, без использования ключевого слова INSTANCE в Java:

public static void main(String args[]) {
    Singleton.INSTANCE.happy();
    Singleton.excited();
}

Запустите программу Java и проверьте вывод следующим образом:

I am Happy
I am very Excited

Если вы нашли эту статью интересной, вы можете изучить Практическое объектно-ориентированное программирование на Kotlin чтобы узнать все, что вам нужно знать об объектно-ориентированном программировании с последними функциями Kotlin 1.3. Практическое объектно-ориентированное программирование на Kotlin дает вам полное понимание концепций программирования, методов объектно-ориентированного программирования и шаблонов проектирования.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *