Java vs. Kotlin для Android. День 1: зістрибує з Java
В черговий раз набираючи на клавіатурі в Android Studio строчки коду з циклом for , зловив себе на думці, що робив це багато разів і вже знаєш кожен наступний оператор, який йде далі. Завдання просте: обрати зі списку безліч елементів, що задовольняє поставленій умові. Начебто нічого складного, все просто: цикл за списком, всередині умова і додавання нового елемента в результуючий список. Ще один стандартний статичний метод у класі з утилітами. Який він там по рахунку вже...- 5ый або 10ый? Буквально 3-4 рядки коду, які зроблять свою справу, АЛЕ чомусь задоволення від виконаної задачі немає. Десь там глибоко є відчуття, що можна робити це простіше. Там же поряд лежать класи-утиліти для роботи з рядками і датами. Скільки їх вже було за весь час?
А тут ще днями Петя/Ваня/Девід сказав, що вони починають новий проект під Android і будуть писати його виключно на Kotlin. Kotlin, а не Java. Чим ця мова краще Java? Скільки вже було цих порожніх нікому не потрібних спроб писати код під Android на PHP/C/C++/С#/Python, і де все це зараз? Можливо, цього разу все по-іншому, і варто звернути на нього увагу? Ну що ж, подивимося, хоча я дуже слабо вірю у щось путнее.
Розробляє його JetBrains і вже давненько, тобто за цей час їх бажання створити свій язик не вичерпалося. Це похвально і заслуговує поваги. Мені подобається їх IDEA & AS. Більш того, головною метою для себе вони ставлять повністю перевести розробку всередині компанії з Java на Kotlin, і хочуть, щоб він, як і Java, використовувався в industry. А ось деякі називають його просто «Swift під Android», от же ж гумористи! І не просто люди з вулиці, а самі розробники Kotlin! Стверджують, що про NPE в рантайме можна забути, що можна розширювати стандартні класи з SDK, що можна лямбды і анонімні функції писати і навіть передавати функції як параметри методи! І навіть крапку з комою прибрали з синтаксису (до речі, ось з цим я згоден на всі 100%). А це прямо-таки з мого PHP-ного минулого — String Templates — по таким речам іноді сумуєш. Забавно, звичайно, але навряд чи все це може стати в нагоді в Android-розробці. Хм, у них є плагін під IDEA/AS і навіть спеціальний плагін під Андроїд проекти. Ось це зараз треба подивитися.
Цікаво виходить — Kotlin на 100% сумісний з Java, і плагін дозволяє java-код в один клік трансформувати в kotlin-код, і це як раз можна перевірити досить швидко. Створимо-ка порожній Android-проект з однією Activity та Fragment всередині, і ще один простий дата-клас теж не завадить.
Беремо шаблонну Activity:
package com.testkotlin; import ... public class TestActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R. layout.activity_test); Toolbar toolbar = (Toolbar) findViewById(R. id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R. id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); } }
і за допомогою дії «Convert Java File to Kotlin File»:
на виході отримуємо ось такий код:
package com.testkotlin; import ... class TestActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R. layout.activity_test) val toolbar = findViewById(R. id.toolbar) as Toolbar setSupportActionBar(toolbar) val fab = findViewById(R. id.fab) as FloatingActionButton fab.setOnClickListener { view -> Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show() } } }
Виглядає непогано, і начебто все зрозуміло. Виходить, що за 100%-ої сумісності з Java нова TestActivity на Kotlin спокійно успадковується від AppCompatActivity , яка лежить в Support Library, а не в SDK. Ну що ж, це досить-таки серйозно полегшує переїзд на рейки Kotlin і робить використання Java-бібліотек безболісним. Безумовно це плюс, мабуть, варто записати очко на користь Kotlin.
Тепер перевіримо, як це спрацює на звичайному дата-класі:
public class Message { private String text; private boolean isRead; public Message(String text, boolean isRead) { this.text = text; this.isRead = isRead; } public String getText() { return text; } public boolean isRead() { return isRead; } }
і конвертнем його в kotlin-файл:
class Message(val text: String, val isRead: Boolean)
Один рядок коду у порівнянні з 14-ю в Java-варіанті! А якщо ще перед описом класу додати data , то автоматом отримуємо можливість робити копії об'єктів за допомогою методу copy() . В якості параметрів він може приймати нові значення полів об'єкта. Запишіть ще одне очко на користь Kotlin.
Це ж на скільки час-то економиться?!?! Ось такого твіста я не очікував, і, побіжно (ну, як швидко...годинки 2) пробігшись по розділу «Classes and Objects» в документації, я дізнався, що:
- для створення екземпляра класу нам не потрібно ключове слово new ;
- ніяких тобі extends або implements , для цього використовується «:»;
- клас може мати один primary constructor і один/декілька secondary constructors ;
- у primary constructor немає тіла, але всередині нього можна описати блок ініціалізації init ;
- використовуються ключові слова var (mutable property)/val (read-only property) для декларації та ініціалізації properties прямо в оголошенні конструктора. Ключові слова val \var використовуються при оголошенні звичайних локальних змінних;
- OMG!, тут єnamed arguments і дефолтні значення для них;
- можна описувати кастомні accessors — круть! дуже корисна штука;
- тепер не потрібно явно викликати getter /setter для отримання/присвоєння значення проперті — звернення відбувається просто по імені — теж здОрово!
- за замовчуванням область видимості для класів/методів/пропертей — public ;
- за замовчуванням усі класи в Kotlin final і потрібно використовувати open -анотацію для класу, якщо необхідно інша поведінка — до цього доведеться трохи звикати;
- інтерфейси тепер можу реалізовувати методи!!! Тобто клас може имплементить два інтерфейсу, які мають різну реалізацію методу з однаковою сигнатурою, і я зможу вибрати, який з методів використовувати. Ось це реально круто! Дуже давно про це мріяв;
- варіативність женериков (узагальнення ) реалізована за допомогою in /out -кейвордів;
- реалізувати anonymous inner classes можна через object expressions & object declarations ;
- всіма улюблений Singleton легко і просто реалізується з допомогою object declaration ;
- Java static methods == object declaration + companion object ;
- делегування реалізовано на рівні декларації класу з допомогою by -clause , компілятор сам згенерує необхідні дублюючі методи — любителі делегування радійте, тепер не потрібно дублювати вручну методи!
Окремо варто відзначити, що фічі, що зачіпають сигнатури методів, також поширюються і на звичайні функції.
А ще можна взяти java-код і скопипастить його в kotlin-файл і IDE сама запропонує його конвертнуть. До речі, на Java можна і в kotlin-файлах спокійно писати код, і все буде працювати — це ще один бонус 100%-ої сумісності. Там же за допомогою IDE отриманий код можна спростити і привести його до kotlin-style. Це здорово допоможе прискорити навчання і зрушити мислення в бік Functional Programming(FP).
Все це виглядає здорово, місцями для закоренілого object-oriented developer незвично, але ж красиво ж! І, головне, що на виході я отримую максимально оптимізований java-код. Так, песимізму по відношенню до цієї мови в мені поменшало.
І я вже збирався лягати спати (на годиннику близько 3-ї ночі), але по дурості взяв і подивився ось цей невеликий доповідь по темі від Jake Wharton і зрозумів, що я занадто перестарався з ігноруванням функціонального програмування. Але цей пробіл я буду заповнювати вже завтра, пардон, сьогодні. Ще й виспатися треба встигнути, і на проекті мене чекає купа бізнес-логіки — знову цикли/умови і статичні методи — а дедлайни ніхто не відміняв. До того ж, буде що розповісти хлопцям за філіжанкою кави по Kotlin-у і прозоро натякнути мою РМ-у, що було б непогано для (компанія, де я працюю) починати підшукувати Android-проект, де замовнику буде все одно на Kotlin-і ми його напишемо або на Java. І розробникам профіт, і компанія може собі в скарбничку ще одну технологію записати.
Опубліковано: 14/03/17 @ 11:01
Розділ Різне
Рекомендуємо:
Як IT-компанії відзначили 8 березня 2017
Front-Еnd дайджест #22: Instagram на React Native, React патерни, Front-End HandBook
Нотатки на полях Java Reflection API
DOU Проектор: Cardiomo – монітор вашого здоров'я
.NET дайджест #15: відродження Alt.NET, .NET Core одним пакетом, що таке микросервис