Меньше кода = меньше ошибок, выше скорость разработки.
В отличие от Java
, в Kotlin
по умолчанию все типы являются non-nullable
, то есть не могут принимать значение null
.
Присвоение или возврат null
приведет к ошибке компиляции.
Чтобы присвоить переменной значение null
, в Kotlin
необходимо явно пометить эту переменную как nullable
(добавив после типа знак вопроса).
В Java
же при использовании ссылки на объект с указанным значением null
, появляется исключение в виде «NullPointerException!»
.
?
?:
!!
Kotlin
позволяет расширять класс путём добавления нового функционала без необходимости наследования от такого класса.
Это реализовано с помощью специальных выражений, называемых расширения.
Например, вы можете написать новые функции для класса из сторонней библиотеки, которую вы не можете изменить. Такие функции можно вызывать обычным способом, как если бы они были методами исходного класса. Этот механизм называется функцией расширения.
fun Context.toast(@StringRes res: Int, short: Boolean = true) {}
Разработчику на Java
приходится писать много стандартного, но часто встречающегося кода (т.н. шаблонный код или boilerplate
).
В Kotlin
же есть возможность создания специальных классов для определения полей для хранения данных, конструктора, функций сеттеров и геттеров для каждого поля, и функций Hashcode()
, toString()
, equals()
и copy()
.
Для этого достаточно добавить data
в определение класса, затем компилятор сделает все сам.
Kotlin
предоставляет возможность создавать дополнительные потоки, однако в нем также существуют т.н. корутины
(сопрограммы), которые позволяют использовать меньше памяти в сравнении с обычным потоком, т.к. реализованы они без стека
.
Корутины
же в свою очередь способны выполнять интенсивные и длительные задачи методом приостановления выполнения без блокировки потока и его последующего восстановления.
Что в дальнейшем позволяет сгенерировать асинхронный
код без блокирования, который при его выполнении не отличить от синхронного. К тому же, они генерируют эффектные доп. стили например async
или await
.
В Java
все должно объявляться внутри класса. Но в Kotlin
все иначе. Компоненты могут объявляться за пределами класса, и это автоматически делает их статическими.
Поэтому нам не требуется ключевое слово static
. В Java
статические члены обрабатываются не так, как члены-объекты.
Это означает, что для статических членов нам недоступны такие вещи, как реализация интерфейса, помещение экземпляра в ассоциативный список (map
) или передача его в качестве параметра методу, который принимает объект.
В Kotlin
static
не является ключевым словом и вместо статических членов используются объекты-компаньоны, позволяющие преодолеть вышеуказанные ограничения. В этом и заключается преимущество.
Даже если члены объектов-компаньонов выглядят как статические члены в других языках, во время выполнения они все равно остаются членами экземпляров реальных объектов и могут, например, реализовывать интерфейсы.