Kotlin

Приведение — это необходимое зло в программировании. Мы обожаем его ненавидеть. В Kotlin выполнять приведение намного приятнее, чем в Java. Читайте ниже об очень известном, малопонятном и чрезвычайно удобном.

Умное приведение в Kotlin

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

private void checkBeforeCast(Object anything) {
if (anything instanceof String) {
println(((String)anything).length());
}
}

Как вы видите из примера выше, несмотря на проверку, вам все равно приходится использовать явное приведение для типа String.

В Kotlin

Уже известно, что anything — это String, поэтому пишем код для умного приведения его к String.

private fun checkBeforeCast(anything: Any) {
if (anything is String) {
println(anything.length)
}
}

CastOrNull в Kotlin: оператор as?

Предположим, мы хотим привести переменную к типу и вернуть null, если приведение не выполнится.

В Java нам бы пришлось написать явный код с проверкой и вернуть null.

private String castOrNull(Object anything) {
if (anything instanceof String) {
return (String)anything;
}
return null;
}

В Kotlin

Используется ключевое слово as?. Оно либо успешно выполняет приведение к данному типу, либо возвращает nullпри неудаче.

private fun castOrNull(anything: Any): String? {
return anything as? String
}

GenericCastOrNull в Kotlin: оператор reified + as?

Пример выше показывает приведение к определенному типу. В Java, если нам потребуются обобщения, которые можно задавать для приведения к любому типу, то придется прибегнуть сразу к двум структурам: T и Class<T>.

private <T> T genericCastOrNull(Object anything, Class<T> clazz) {
if (clazz.isInstance(anything)) {
return (T)anything;
}
return null;
}

Вызов этого класса выглядит так:

String myString = genericCastOrNull(anything, String.class)

В Kotlin

Можно достичь того же самого следующим синтаксисом:

private inline fun <reified T> genericCastOrNull(anything: Any):T? {
return anything as? T
}

Вызов функции выглядит так:

val myString = genericCastOrNull<String>(anything)

Перевод статьи Elye: Kotlin made casting so much neater