JavaRush /Java блог /Random UA /KotlinRush: а чи є сенс продовжувати писати на Java?
NikEy
41 рівень
Новосибирск

KotlinRush: а чи є сенс продовжувати писати на Java?

Стаття з групи Random UA
Привіт, студент JavaRush, поки тебе цілком і повністю не поглинула Java, я хотів би розширити твій кругозір і звернути увагу на мову Kotlin , що набирає популярності !
KotlinRush: а чи є сенс продовжувати писати на Java?  - 1
Kotlin - досить молода мова, розроблена компанією JetBrains . Так-так, саме тією компанією, яка розробила нашу улюблену IDE: IntelliJ IDEA. Kotlin є JVM мовою і повністю сумісний з Java , тобто з Kotlin-коду можна без проблем звертатися до звичних Java-бібліотеків, Та що там до бібліотек: Kotlin та Java класи можуть вживатися в одному package! Kotlin настільки сподобався спільноті програмістів, що Google визнав його офіційною мовою розробки під Android, а останнім часом Kotlin почав набирати популярності і в ентерпрайз-проектах. У цій статті я хотів би навести кілька порівняльних прикладів коду, написаного на Kotlin і Java, і зробити деякі висновки. Поїхали! Почнемо за традицією з "Hello World"
// Java
public class Application {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
// Kotlin
class Application
fun main(vararg args: String) {
    println("Hello World!")
}
Дивлячись на приклад Kotlin, можна відразу відзначити таке:
  • не потрібно писати крапку з комою в кінці рядка;
  • всі методи описуються ключовим словом fun ;
  • щоб вивести рядок достатньо одного слова - println() !
Створення екземпляра
// Java (до 10)
final Application application = new Application();
// Kotlin
val application = Application()
Відмінності Kotlin:
  • не потрібно оголошувати тип змінної, якщо він зрозумілий за екземпляром;
  • замість типу змінної - val (незмінна) або var (змінна);
  • для створення екземпляра не потрібно писати ключове слово new !
Опис методів
// Java
public int sum(int a, int b) {
    return (a + b);
}
// Kotlin
fun sum(a: Int, b: Int): Int {
return (a + b)
}
Відмінності Kotlin:
  • якщо з методу потрібно щось повернути, в сигнатуру додається " : Int ", де Int - тип, що повертається;
  • опис параметрів методу: спочатку ім'я змінної, потім тип;
  • Оскільки тіло методу складається всього з одного рядка, можна опустити return :
    fun sum(a: Int, b: Int): Int = (a+b)
Форматований виведення рядків
// Java
public int sum(int a, int b) {
    int result = (a + b);
    System.out.printf("Сумма %d и %d равна %d\n", a, b, result);
    return result;
}
// Kotlin
fun sum(a: Int, b: Int): Int {
    val result = (a + b)
    println("Сумма $a и $b равна $result")
    return result
}
Kotlin підтримує інтерполяцію рядків, достатньо використовувати символ "$" спочатку змінної. Такий запис значно підвищує чистоту та читабельність коду. Порівняння екземплярів
// Java
object1.equals(object2)
// Kotlin
object1 == object2
У Kotlin порівняння ==для об'єктних типів транслюється в equals! Для порівняння посилань використовується " ===" . Винятки
// Java
public List<String> getFileContent(String file) throws IOException {
    Path path = Paths.get(file);
    return Files.readAllLines(path);
}
// Kotlin
fun getFileContent(file: String): List<String> {
    val path = Paths.get(file)
    return Files.readAllLines(path)
}
У Kotlin немає checked винятків, тепер не потрібно нескінченно прокидати виняток через всю програму або городити багаторівневі try-catch. Null Safety
// Java
public class Data {
    String value;

    String render() {
        if (value == null) {
            return "Value: undefined";
        } else {
            return "Value:" + value.toUpperCase();
        }
    }
}
// Kotlin
class Data {
    var value: String? = null
    fun render(): String =
            "Value: ${value?.toUpperCase() ?: "undefined"}"
}
У Kotlin перейнялися проблемою NPE і ввели низку вимог:
  • всі поля класу та змінні обов'язково повинні бути проініціалізовані;
  • у полі чи змінну можна записати "null", але тоді ти зобов'язаний явно сказати, що твоя змінна Nullable (написати знак "?");
  • елвіс-оператор "?:" працює наступним чином: якщо зліва Null, візьми те, що вказано праворуч. У разі нашого прикладу, коли змінна value не проініціалізована, візьметься значення " undefined " .
Поля класу та доступ до них
// Java
public class Data {
    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}
class App {
    void execute() {
           Data data = new Data()
           data.setValue("Foo")
     }
}
// Kotlin
class Data {
    var value: String = ""
}
class App {
    fun execute() {
          val data = Data()
          data.value = "Foo" // Под капотом выполнится data.set("Foo")
     }
}
У Kotlin досить просто описати поле і все: у нього вже є неявні гетери та сеттери (привіт lombok ), які за бажання будь-якої миті можна перевизначити. При цьому читаємо та модифікуємо значення поля просто звертаючись безпосередньо до нього, а під капотом викликається get()|set(). Цикли
// Java
void example() {
    for(int i = 1; i <= 10; i++) {
        System.out.println(i);
    }

    for(String line : "a,b,c".split(",")) {
        System.out.println(line);
    }
}
// Kotlin
fun example() {
    for(i in 1..10) {
        println(i)
    }

    for(line in "a,b,c".split(",")) {
        println(line)
    }
}
Kotlin надав зручний та одноманітний синтаксис обходу послідовностей: ти просто використовуєш зліва змінну, праворуч послідовність, а між ними – ключове слово " in ", тип визначається автоматично за вмістом. Сінглтон
// Java
public class Singleton {
    private static Singleton ourInstance = new Singleton();

    public static Singleton getInstance() {
        return ourInstance;
    }

    private Singleton() {
    }
}
class App {
    void execute() {
         Singleton singleton = Singleton.getInstance()
    }
}
// Kotlin
object Singleton {}

class App {
    fun execute() {
          val singleton = Singleton
    }
}
Знайомий всім патерн " одиначка " досить часто використовується на практиці, тому в Kotlin вирішабо створити окреме ключове слово " object ", яке пишеться замість " class " і означає, що клас є синглтоном, при використанні навіть не потрібно звати конструктор або будь-які інші методи! Іменовані параметри методів та дефолтні значення
// Java
void setStatus(String code) {
    setStatus(code, "");
}

void setStatus(String code, String desc) {
    this.code = code;
    this.desc = desc;
}
// Kotlin
fun setStatus(code: String, desc: String = "") {
    this.code = code;
    this.desc = desc;
}

fun execute() {
    setStatus("200")
    setStatus(code = "200", desc = "Ok")
}
Трапляється таке, що не всі параметри в методі або конструкторі повинні бути обов'язковими, і Java ми звикли створювати набір методів або конструкторів під комбінацію параметрів. У Kotlin ввели дефолтні параметри, що дозволяє оголосити один метод і передавати в нього необхідний набір параметрів ситуації. Стрими
// Java
String getFirst(List<String> strings, String alpha) {
    return strings.stream()
            .filter(x -> x.startsWith(alpha))
            .findFirst()
            .orElse("");
}
// Kotlin
fun getFirst(strings: List<String>, alpha: String): String {
    return strings.first { it.startsWith(alpha) }
}
Stream в Java 8 стали невід'ємним функціоналом при роботі з колекціями. У Kotlin стрими зробабо ще зручнішими і функціональнішими: кожна колекція вже має набір зручних часто використовуваних методів для роботи з даними. Крім того, зверніть увагу на лямбда вираз усередині методу first: якщо функціональний літерал має рівно один параметр, його оголошення можна видалити (разом з ->), і звертатися до нього на ім'я  it . Настав час закруглюватися... Я продемонстрував лише малу, базову частину функціоналу, але, я впевнений, тобі вже захотілося спробувати Kotlin! За своїм досвідом я можу зробити такі висновки:
  • Java розробнику дуже легко освоїти синтаксис Kotlin та почати писати код;
  • у Kotlin повна сумісність з Java, і його вже можна пробувати у своїх проектах, що діють, наприклад, у тестах;
  • код на Kotlin чистіший і читабельніший, не потрібно писати купу бойлерплейта ;
  • у IDEA є автоматичний конвертер Java у Kotlin, ви можете брати готовий Java-код і автоматично конвертувати його у Kotlin;
  • новий проект потрібно писати на Kotlin, тому що з інфраструктурної точки зору це та ж Java, а по використанню краще і зручніше!
Якщо стаття сподобалася і доречна на ресурсі про Java, можу продовжити писати про досвід використання Kotlin в реальному ентерпрайзному проекті. Корисні посилання:
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ