Pull to refresh

Comments 19

если в дальнейшем кто-то захочет расширить функционал Java-метода, добавив обработку null-значения, и уберёт аннотацию @NotNull (не проставив @Nullable) — то это никак не отразится на компиляции Kotlin-кода, и в нём опять возникнет риск получить NPE в рантайме

О да, у нас был как раз такой случай. У нас старый код написал на Джаве, а новый на Котлине. И один из разработчиков решил добавить в метод джавакода возможность обрабатывать null, и просто убрал NotNull, а Nullable не проставил... Итог был предсказуем :(

Другие описанные случаи я не встречал.

Такое на код-ревью не ловится разве?

В теории должно ловиться, а на практике ревьювер не заметил.

Какой всё-таки смысл переходить с Java на Котлин?

Это не из-за этого в Андроиде вдруг getText() у EditText начал требовать проверку на null, хотя в здравом уме такое представить нереально?

Какой всё-таки смысл переходить с Java на Котлин?

Гугл будет дальше еще сильнее пушить Котлин через свои библиотеки. Компоуз работает только с Котлином, а новые АндроидХ либы уже имеют курутины как часть стандартного апи, а не в виде дополнительных Колин экстеншонов.

Ну и что? Сейчас можно написать код на яве и отделив представление получить с мнимальными правками универсальное приложение работающее на всех основных ОС.

Google выиграл у Oracle в суде многолетнюю тяжбу об использовании Java.

Таким образом, ничто не мешает на Android использовать Java.

В чём выгода разрабочикам в сегментировании?

Google выиграл у Oracle в суде многолетнюю тяжбу об использовании Java

Суд был про реализацию Java API, а не саму Java. Если бы проиграли, то Котлин бы не спас, т.к. он сам использует Java API.

Котлин полностью совместим с джавой. Почему нельзя написать код на котлине, и запускать его везде, где работает джава? К тому же у котлина есть своя мультиплатформа которая активно развивается. Возможности котлина позволяют писать код, более короткий, чем на джаве. Меньше кода -> меньше ошибок, и проще его читать.

Какой всё-таки смысл переходить с Java на Котлин?

Лично мне Kotlin кажется просто более приятным и удобным, чем Java. В нём имеется множество фич, которые уже давно есть в других языках, но в Java нет - например, дефолтные значения у аргументов функций. Когда возвращаешься назад на Java, то подобных фич как раз не хватает.

Ну и в целом код, написанный на Kotlin, лично мне становится немного проще читать. Он выглядит лаконичнее, что ли.

В нём имеется множество фич... например, дефолтные значения у аргументов функций....

Ну и в целом код, написанный на Kotlin, лично мне становится немного проще читать.

Разве это не противоречие? Если в вызовах не видны значения всех аргументов, разве это упрощает понимание? Это несомненно упрощает написание в момент, когда помнишь и знаешь особенности вызова, но упрощает ли чтение и понимание?

Фича "дефолтных значений аргументов" опциональна, никто не заставляет её использовать. Если не нужна читаемость - можно не указывать дефолтные аргументы, если нужна - тогда можно указать. Более того, если нужна совсем максимальная читаемость - то Котлин для этого как раз поддерживает вызовы функций с именованными аргументами , чего в Java тоже нет. В общем, у программиста хотя бы есть выбор)

>Разве это не противоречие? Если в вызовах не видны значения всех аргументов, разве это упрощает понимание?

Если писать в блокноте, то - противоречие. А если в IDE, то наоборот. Потому, что вы в подсказке увидите сигнатуру метода со всеми дефолтами.

В plain java же, в этом случае у вас будет цепочка перегруженных методов в которые добавляются параметры по-одному. И писанины больше и итоговый вызов вы увидите только пройдя по цепочке.

private String whatWasTheQuestion() {
    return whatWasTheQuestion("The Ultimate Question of Life, the Universe, and Everything");
}
private String whatWasTheQuestion(String question) {
    return someMethod(question, 42);
}
private String whatWasTheQuestion(String question, int answer) {
    return someMethod(question, answer, "mice");
}
private String whatWasTheQuestion(String question, int answer, String builders) {
    return makeOrderToConstructSupercomputerForLookingForTheQuestionForTheAnswer(builders)
        .setQuestion(question)
        .setAnswer(answer)
        .build()
        .ask();
}

В котлине будет сразу всё видно:

fun whatWasTheQuestion(question: String = "The Ultimate Question of Life, the Universe, and Everything",
     answer: Int = 42,
     builders: String = "mice"): String =
          makeOrderToConstructSupercomputerForLookingForTheQuestionForTheAnswer(builders).question(question).answer(answer).build().ask()

А разве такая перегрузка функций, как вы показали для явы, не должна ставится под сомнение на этапе их создания? Как вариант - сменить название функций.

А разве такая перегрузка функций, как вы показали для явы, не должна ставится под сомнение на этапе их создания?

А почему должна? Мой пример, разумеется, утрированный, но это общепринятая практика. Чаще, наверное, в виде набора конструкторов с пачкой необязательных параметров. Ну, чтобы не писать new MyObject("important param", null, null, null, null). Понятно, что для этого есть паттерн Builder, но писать билдеры, поддерживать и копаться в них - тот ещё геморрой. Конечно, мы их сейчас не пишем - всё делает Lombok, но это как раз костыль и покрывает он только вариант с конструкторами, а так-то и обычные методы достаточно часто перегружают таким образом.

Как вариант - сменить название функций.

А смысл? Они же не исчезнут от этого и способ их использования не изменится, только путаницы прибавится. Если семантика у методов разная, то, да, разумеется, нужно называть по-разному. Но тут речь именно от случае когда семантика одна, просто набор параметров разный.
Простой пример - логгер
log.error("message");
и
log.error("message", exception);
их можно поименовать log.errorWithMessage и log.errorWithMessageAndException соответственно. Писать дольше, путаницы больше, а реализация первого метода - это всё равно вызов this.errorWithMessageAndException(message, null) - никакой пользы, кроме вреда :).

геттера getReference() класса FirebaseDatabase, который не просто возвращает нам уже существующий объект класса DatabaseReference, а каждый раз создаёт его заново.

Ну здесь проблема в том что метод, который создаёт, назвали геттером, а вовсе не в котлине. С тем же успехом можно и в любом другом языке его неправильно использовать.

Я согласен с тем, что это не проблема языка. Просто обратил внимание читателя на том, что данную фичу нельзя использовать бездумно.

Отмечу, что в упомянутой в начале статье упомянуты не какие-то синтетические методы выстрелов в ногу, а "основанные на реальных событиях". Стоит учесть, что это 2016 год, 5 лет назад. Сам язык мы начали использовать еще до официального релиза 1.0, и некоторые концепты, очевидные сейчас, тогда были еще новы.

Еще один подводный камень при разработке на Kotlin.
Обновил PATCH версию com.soywiz.korlibs.klock:klock c 2.0.1 до 2.0.7.

Получил несовместимость ABI

The abi versions don't match. Expected '[1.4.1]', found '1.4.2'. The library produced by 1.4.31 compiler

Sign up to leave a comment.

Articles