Миграция с Явы в Котлин
1. обзор
В этом руководстве мы рассмотрим, как перейти с Java наKotlin. Хотя мы рассмотрим множество основных примеров, эта статья не является введением в Kotlin. Для отдельной статьи вы можете начать сthis writeup here.
Здесь мы рассмотрим основные примеры переноса нашего Java-кода на Kotlin, такие как простые операторы печати, определение переменных, управление допуском к значениям NULL.
Затем мы перейдем к внутренним областям, таким как управляющие операторы, такие как if-else и операторы switch.
Наконец, мы переходим к определению классов и работе с коллекциями.
Дальнейшее чтение:
Классы данных в Котлине
Быстрый и практический пример использования классов данных в Kotlin.
Модификаторы видимости в Котлине
Откройте для себя модификаторы видимости Kotlin и посмотрите, чем они отличаются от модификаторов Java.
Всеобъемлющее руководство по нулевой безопасности в Котлине
Краткое практическое руководство по нулевым функциям безопасности, встроенным в язык программирования Kotlin.
2. Основные миграции
Давайте начнем с простых примеров того, как переносить простые утверждения.
2.1. Печатать заявления
Для начала давайте посмотрим, как работает печать. В Java:
System.out.print("Hello, example!");
System.out.println("Hello, example!");
В Котлине:
print("Hello, example!")
println("Hello, example!")
2.2. Определение переменных
В Java:
final int a;
final int b = 21;
int c;
int d = 25;
d = 23;
c = 21;
В Котлине:
val a: Int
val b = 21
var c: Int
var d = 25
d = 23
c = 21
Как мы видим, точки с запятой в Kotlin являются необязательными. Kotlin также использует расширенный вывод типов, и нам не нужно явно определять типы.
Всякий раз, когда мы хотим создать конечную переменную, мы можем просто использовать“val” вместо“var”.
2.3. Кастинг
В Java нам нужно выполнить ненужное приведение в таких ситуациях, как:
if(str instanceof String){
String result = ((String) str).substring(1);
}
В Kotlin умное приведение позволяет нам пропускать избыточное приведение:
if (str is String) {
val result = str.substring(1)
}
2.4. Битовые операции
Битовые операции в Kotlin намного более интуитивны.
Давайте посмотрим, как это работает на Java:
int orResult = a | b;
int andResult = a & b;
int xorResult = a ^ b;
int rightShift = a >> 2;
int leftShift = a << 2;
А в Котлине
var orResult = a or b
var andResult = a and b
var xorResult = a xor b
var rightShift = a shr 2
var leftShift = a shl 2
3. Нулевая безопасность
В Java:
final String name = null;
String text;
text = null;
if(text != null){
int length = text.length();
}
Итак, в Java нет ограничений на присвоение переменных null и их использование. При использовании любой переменной мы обычно также вынуждены делать нулевую проверку.
Это не тот случай с Kotlin:
val name: String? = null
var lastName: String?
lastName = null
var firstName: String
firstName = null // Compilation error!!
По умолчанию Kotlin предполагает, что значения не могут бытьnull.
Мы не можем присвоитьnull ссылкеfirstName, и если мы попытаемся это сделать, это вызовет ошибку компилятора. Если мы хотим создать пустую ссылку, нам нужно добавить знак вопроса (?) К определению типа, как мы это делали в первой строке.
Подробнее об этом можно прочитать вthis article.
4. Строковые Операции
Strings работают так же, как в Java. Мы можем проделать аналогичные операции, такие какappend, а также получить частьString.
В Java:
String name = "John";
String lastName = "Smith";
String text = "My name is: " + name + " " + lastName;
String otherText = "My name is: " + name.substring(2);
String text = "First Line\n" +
"Second Line\n" +
"Third Line";
В Котлине:
val name = "John"
val lastName = "Smith"
val text = "My name is: $name $lastName"
val otherText = "My name is: ${name.substring(2)}"
val text = """
First Line
Second Line
Third Line
""".trimMargin()
Это выглядело довольно легко:
-
Мы можем интерполироватьStrings с помощью символа“$”, и выражения будут оцениваться во время выполнения. В Java мы могли бы добиться чего-то подобного, используяString.format()
-
Нет необходимости ломать многострочные строки, как в Java. Kotlin поддерживает их использование "из коробки". Нам просто нужно помнить, чтобы использовать тройные кавычки
В Котлине нет символа продолжения линии. Поскольку его грамматика позволяет иметь пробелы между почти всеми символами, мы можем просто разбить выражение:
val text = "This " + "is " + "a " +
"long " + "long " + "line"
Однако, если первая строка оператора является допустимым, это не сработает:
val text = "This " + "is " + "a "
+ "long " + "long " + "line" // syntax error
Чтобы избежать таких проблем при разбиении длинных операторов на несколько строк, мы можем использовать круглые скобки:
val text = ("This " + "is " + "a "
+ "long " + "long " + "line") // no syntax error
5. Циклы и операторы управления
Как и в любом другом языке программирования, в Kotlin есть управляющие операторы и циклы для повторяющихся задач.
5.1. Для петли
В Java у нас есть различные типы циклов для перебора коллекции илиMap,, например:
for (int i = 1; i < 11 ; i++) { }
for (int i = 1; i < 11 ; i+=2) { }
for (String item : collection) { }
for (Map.Entry entry: map.entrySet()) { }
В Kotlin у нас есть нечто подобное, но проще. Как мы уже знаем, синтаксис Kotlin пытается максимально имитировать естественный язык:
for (i in 1 until 11) { }
for (i in 1..10 step 2) { }
for (item in collection) { }
for ((index, item) in collection.withIndex()) { }
for ((key, value) in map) { }
5.2. Switch иWhen
Мы можем использовать операторыswitch в Java для принятия выборочных решений:
final int x = ...; // some value
final String xResult;
switch (x) {
case 0:
case 11:
xResult = "0 or 11";
break;
case 1:
case 2:
//...
case 10:
xResult = "from 1 to 10";
break;
default:
if(x < 12 && x > 14) {
xResult = "not from 12 to 14";
break;
}
if(isOdd(x)) {
xResult = "is odd";
break;
}
xResult = "otherwise";
}
final int y = ...; // some value;
final String yResult;
if(isNegative(y)){
yResult = "is Negative";
} else if(isZero(y)){
yResult = "is Zero";
} else if(isOdd(y)){
yResult = "is Odd";
} else {
yResult = "otherwise";
}
В Kotlin вместо оператораswitch мы используем операторwhen для принятия выборочных решений:
val x = ... // some value
val xResult = when (x) {
0, 11 -> "0 or 11"
in 1..10 -> "from 1 to 10"
!in 12..14 -> "not from 12 to 14"
else -> if (isOdd(x)) { "is odd" } else { "otherwise" }
}
Операторwhen может действовать как выражение или оператор с аргументом или без него:
val y = ... // some value
val yResult = when {
isNegative(y) -> "is Negative"
isZero(y) -> "is Zero"
isOdd(y) -> "is odd"
else -> "otherwise"
}
6. Классы
В Java мы определяем класс модели и сопровождаем их стандартными установщиками и получателями:
package com.example;
public class Person {
private long id;
private String name;
private String brand;
private long price;
// setters and getters
}
В Котлине геттеры и сеттеры генерируются автоматически:
package com.example
class Person {
var id: Long = 0
var name: String? = null
var brand: String? = null
var price: Long = 0
}
Также можно изменить видимость геттера / сеттера, но имейте в виду, что видимость геттера должна быть такой же, как видимость свойства.
В Kotlin каждый класс поставляется со следующими методами (могут быть переопределены):
-
toString (читаемое строковое представление объекта)
-
hashCode (предоставляет уникальный идентификатор объекта)
-
equals (используется для сравнения двух объектов из одного и того же класса, чтобы увидеть, одинаковы ли они)
7. Коллекции
Ну, мы знаем, что Коллекции - это мощная концепция для любого языка программирования; Проще говоря, мы можем собирать подобные объекты и выполнять операции с ними. Давайте взглянем на них на Java:
final List numbers = Arrays.asList(1, 2, 3);
final Map map = new HashMap();
map.put(1, "One");
map.put(2, "Two");
map.put(3, "Three");
// Java 9
final List numbers = List.of(1, 2, 3);
final Map map = Map.of(
1, "One",
2, "Two",
3, "Three");
Теперь в Котлине мы можем иметь похожие коллекции:
val numbers = listOf(1, 2, 3)
val map = mapOf(
1 to "One",
2 to "Two",
3 to "Three")
Выполнение операций также интересно, как в Java:
for (int number : numbers) {
System.out.println(number);
}
for (int number : numbers) {
if(number > 5) {
System.out.println(number);
}
}
Далее, мы можем выполнить те же операции в Kotlin намного проще:
numbers.forEach {
println(it)
}
numbers
.filter { it > 5 }
.forEach { println(it) }
Давайте рассмотрим последний пример сбора четных и нечетных чисел вMap изString в качестве ключей иList изIntegers в качестве их значения. На Java нам нужно будет написать:
final Map> groups = new HashMap<>();
for (int number : numbers) {
if((number & 1) == 0) {
if(!groups.containsKey("even")) {
groups.put("even", new ArrayList<>());
}
groups.get("even").add(number);
continue;
}
if(!groups.containsKey("odd")){
groups.put("odd", new ArrayList<>());
}
groups.get("odd").add(number);
}
В Котлине:
val groups = numbers.groupBy {
if (it and 1 == 0) "even" else "odd"
}
8. Заключение
Эта статья служит начальной справкой при переходе с Java на Kotlin.
Хотя сравнение было лишь намеком на то, насколько простым и интуитивно понятным может быть Kotlin, другие статьиcan be found here.