Пользователь Paul Soia
Paul Soia
26 уровень
Киев

Есть ли отличие Kotlin от Java?

Статья из группы Android
Всем привет. Хочу рассказать немного базовых вещей о языке Kotlin, что будет полезно новичкам. Так уж сложилось, что сейчас попасть в android-разработку только с одним языком будет сложно — большинство новых проектов начинают писать на Kotlin, большинство готовых проектов написаны на Java. Есть ли отличие Kotlin от Java? - 1На данный момент у меня на работе 4 проекта: два на Kotlin и два на Java (один большой основной и три маленьких, для внутреннего пользования). Когда компанией было принято решение писать новые проекты на Kotlin, для меня это решение казалось странным. Зачем мешать разные языки? Пусть себе кто-то другой пишет на Kotlin, нам оно зачем? Но выхода не было, потому решил опробовать новый язык и начал его изучать. Первый код, естественно, был полностью написан в стиле Java, что еще больше добавляло непонимания: зачем мне новый язык? Но по мере его использования я всё больше находил преимуществ и сейчас (уже почти 2 года пишу на Kotlin) могу сказать, что в андроид-разработке Kotlin удобнее. Хочу показать некоторые нюансы, которые будут неочевидны для того, кто решил начать изучать Kotlin после Java. Также напомню, что в андроиде используется Java 8, при нынешней актуальной версии 14. Итак, первое — Переменные: Java:

        Int a = 1;	
	String s = "test";
Kotlin:

        val a = 1
        var b = 2
        val c: Int
        val d = "test" 
В Kotlin переменные двух типов: val (только для чтения) и var (для чтения и записи). Рекомендуется использовать val везде, где это возможно. Объявлять тип переменной не обязательно, если переменная уже инициализирована. Второе — выражения if/else, switch: Как часто вы используете в Java такую цепочку операторов:

if (вариант 1)
{...}
else if (вариант 2)
{...}
...
else
{...}
Или так:

switch(выражениеДляВыбора) {
        case (значение 1):
                Код1;
                break;
        case (значение 2):
                Код2;
                break;
...
        case (значение N):
                КодN;
                break;
        default:
                КодВыбораПоУмолчанию;
                break;
        }
В Kotlin используется для таких выражений оператор when (хотя if/else тоже можно использовать):

val x = 5
val result = when(x) {
        0, 1 -> "cool"
        2 -> "bad"
        5 -> "normal"
        else -> "error"
}
System.out.println(result)
Здесь мы не просто прошлись по цепочке условий, а еще и всё выражение сразу присвоили в переменную result, что сократило нам немало строк кода. Но всё же если у вас только два варианта в ветвлении, рекомендую использовать обычный if..else. Конструкция when будет короче только от трех вариантов. Идем дальше — Конструкторы. Здесь вообще сказка. Просто сравните код в Java и Kotlin. Java:

public class Person {
    
    private String firstName;
    private String lastName;
    private int age;

    public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
Kotlin:

 class Person(private val firstName: String, 
             private val lastName: String, 
             private var age: Int) {
}
Может показаться, что в коде на котлине что-то не дописали. Но нет, это два идентичных кода на разных языках. Давайте немного разберемся. В Kotlin конструктор можно прописывать прямо в теле названия класса (но если хочется, то можно и по старинке, как в Java). Итак, мы прописали три переменные, в Java создали конструктор, геттеры и один сеттер для переменной age. В Kotlin, как мы помним, переменная val только для чтения, а потому сеттер для этих переменных недоступен (геттеры-сеттеры котлин реализует под капотом сам). Переменная var дает возможность использовать сеттер. В итоге практически одной строкой мы написали то же самое, что на Java заняло больше десятка строк. Здесь рекомендую еще почитать про data class в Kotlin. Но это еще не всё, в чем хороши конструкторы в Kotlin. А что, если вам надо два конструктора? А если три? В Java это будет выглядеть так:

public Person(String firstName, String lastName, int age) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }

public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

public Person(String firstName) {
        this.firstName = firstName;
    }
Ничего сложного, сколько надо конструкторов, столько и сделали. В Kotlin можно обойтись одним конструктором. Как? Всё просто — значения по умолчанию.

class Person(private val firstName: String,
             private val lastName: String? = null,
             private var age: Int = 5) {
}
Мы в конструкторе присвоили значения по умолчанию и теперь вызов их будет выглядеть так:

Person(firstName = "Elon", lastName = "Mask", age = 45)
Person(firstName = "Elon", age = 45)
Person(firstName = "Elon", lastName = "Mask")
Тут может возникнуть вопрос: что это такое:

private val lastName: String? = null
Что еще за знаки вопроса? Да, если значение может быть null, то ставится ?.Также есть вариант вот такой — !! (если переменная не может принимать null). Об этом уже сами почитайте, там всё просто. А мы идем к следующему пункту. Extensions. Это очень крутой инструмент в Kotlin, которого нету в Java. Иногда мы в проекте используем шаблонные методы, которые повторяются во многих классах. Например, так:

Toast.makeText(this, "hello world :)", Toast.LENGTH_SHORT).show();
В Kotlin мы можем сделать расширение для класса:

fun Context.toast(message: CharSequence) = Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
И дальше по всему проекту использовать это вот так:

context?.toast("hello world")
Мы сделали расширение для класса Context. И теперь везде, где доступен context, будет доступен его новый метод toast. Это можно сделать для любого класса: String, Fragment, ваши кастомные классы, ограничений нет. И последний пункт, который разберем — Работа со строками. Тут всё просто. В Java это пишется так:

String s = "friends";
int a = 5;
System.out.println("I have" + a + s + "!");
В Kotlin проще:

val s = "friends"
val a = 5
println("I have $a $s!")
Это те нюансы, на которых я спотыкался в начале изучения Kotlin, надеюсь вам это поможет.
Комментарии (23)
Чтобы просмотреть все комментарии или оставить свой, перейдите в полную версию
Mihail 19 уровень, Саранск
10 августа 2020
Да-а-а , с API наверное тоже всё само взаимодействует. Приведите какой нибудь пример, интересно же:) Вот так всегда только начнёшь учить язык, проходит год, всё он устарел, учи другой. Учишь другой , прошло полгода, узнаешь что появился ещё один. Дайте первый то доучить:)
Павел Шабанов 32 уровень, Киев
2 августа 2020
Kotlin по сравнению с Java более лаконичен, меньше лишнего кода + null safety из коробки. И т.к. гугл объявили Kotlin приоритетным языком под android, то стоит как минимум с ним познакомиться. Думаю многим мобильным разработчикам придется пройти через отрицание, гнев, принятие. К тому же никто не запрещает вызывать код java из kotlin и наоборот :)
Сергеев Виктор 40 уровень, Санкт-Петербург
31 июля 2020
Extensions вот это штука меня как-то в ступор поставила на ревью, когда увидел у мапы специфичный для нас метод )
Ксенія Mario 23 уровень, Киев
28 июля 2020
не вели слать в гугл, а вели слово молвить) а чем принципиальным отличается котлин и джава?
Сергей 40 уровень, Москва
26 июля 2020
По поводу объявления переменных, тоже самое есть в java. C 11 версии можно объявлять черех var. C библиотекой lombok можно объявлять через val (с 8 java точно) Однако, удобство сомнительное. С одной стороны эта запись короче. Но с другой, ты видишь стразу, что возвращает метод, тогда как с записью val, это не понятно. Вот пример. Что возвращает метод во второй строке, непонятно. Нужно делать дополнительные действия чтобы это выяснить.

String result = someMethod();

val res = anotherMethod();
Вообще библиотека lombok, о которой я писал добавляет много таких фишек в java. В результате отличия минимальны и недостаточны для перехода с java на kotlin. Отказ от java в пользу kotlin в Android это чисто политическое решение Google. Oracle давно судятся из-за нарушения авторских прав https://ain.ua/special/google-vs-oracle/
Александр Плохой 41 уровень, Москва
26 июля 2020
Kotlin представляет интерес исключительно для тех, кто вообще не знает Java.. и крайне сомнительный интерес)
Сергей 40 уровень, Москва
26 июля 2020
По поводу конструкторов спорное удобство. Переменные в классе будут объявлены частично в конструкторе, а частично в самом классе, что не очень удобно.