O Javie można mówić w dwojaki sposób, albo o jednym z najbardziej popularnych języku programowania na świecie, albo o maszynie wirtualnej, którą chyba każdy z nas kiedyś instalował na swoim komputerze, zwanej też, cytując stopkę na stronie https://www.java.com/pl/download/.
„Java Runtime, Runtime Environment, Runtime, JRE, Java Virtual Machine, maszyna wirtualna Java, Java VM, JVM, VM, wtyczka Java, Java Plug-In, dodatek Java lub Java Download.”
Język Java i JVM są od siebie niezależne, chodzi tutaj o to, że kod napisany w Javie nie jest bezpośrednio uruchamiany na JVM, przed uruchomieniem ten kod jest kompilowany do kodu bajtowego i dopiero wtedy uruchamiany.
I tutaj mamy pewną furtkę, którą wykorzystała firma JetBrains. Doszli oni do bardzo prostego wniosku, że nie ważne w czym, ważne aby wygenerować kod bajtowy, który będzie wykonywany na JVM. Takie rozwiązanie ma jeszcze jedną bardzo dużą zaletę. Mianowicie kod napisany w Kotlinie i skompilowany, można bez problemu wykorzystać w normalnych projektach pisanych w Javie.
Oczywiście nie obyło się bez dodatkowych wtyczek, kompilatorów itp., które w pewnym sensie opakowują język Javę, ale o tym kiedy indziej.
Wszystko fajnie, ale co z tego? W czym ten Kotlin jest lepszy od zwykłej Javy? Przecież dalej to jest JVM i do tego można jeszcze odnieść wrażenie, że jest wolniejszy, bo przecież go opakowujemy jakimiś dodatkowymi rzeczami.
Krótka odpowiedź: Kotlin jest po prostu Javą 2.0.
Dłuższa odpowiedź:
Każdy język da się porównać z innym językiem. Nie można oczywiście powiedzieć, C# jest lepszy od Javy, albo C++ jest lepszy od Pythona, a PHP to totalne dno. To tak jakby powiedzieć, że młotek jest lepszy od piły. Bezsens. Można natomiast porównać pewne cechy zarówno samego języka, jak i całego rozwiązania albo nawet ekosystemu, no bo czym byłaby Java bez JVM. Część tych cech jest subiektywna, a część obiektywna i dla każdego z nas mogą mieć one inny priorytet. Moim zdaniem dwa najważniejsze z nich to:
- Szybkość działania, zasobożerność, zużycie energii: Wbrew pozorom Java, a jeszcze dokładniej JVM wcale nie jest taki wolny na jakiego wygląda, nie jest to oczywiście assembler, C czy C++ ale dzięki wielu różnego rodzaju sztuczkom w JVM-ie jest on przyzwoicie szybki. Na potwierdzenie tych słów można zerknąć na benchmarki, Java wypada w nich naprawdę przyzwoicie https://attractivechaos.github.io/plb/. Podobnie jest z energią, natomiast z zasobami już jest trochę gorzej. Więcej na ten temat można przeczytać tutaj: https://thenewstack.io/which-programming-languages-use-the-least-electricity/. Kotlin wypada w porównaniu do Javy trochę gorzej, ale są to wartości naprawdę małe.
- Jak szybko można pisać kod: To jest dość subiektywne, ponieważ każdy z nas koduje w różnym tempie, ale z doświadczenia mogę powiedzieć, że Kotlin jest o wiele łatwiejszy zarówno do nauczenia się, jak i wykorzystania, a wynika to z prostego faktu, język ten jest pragmatyczny. Został napisany przez programistów z wieloletnim doświadczeniem, aby w łatwy sposób rozwiązywać ich problemy. Zawiera o wiele wyższy poziom abstrakcji oraz składa się z elementów, które są po prostu sprawdzone.
Dodatkowo można tutaj porównać jeszcze takie rzeczy jak: wsparcie środowiska (Java oczywiście tutaj wygrywa, ale Kotlin też ma się całkiem dobrze), liczbę developerów znających ten język, liczbę bibliotek i wiele, wiele więcej.
Ja chciałbym bardziej skupić na tym drugim punkcie i opisać klika podstawowych rzeczy, na które składa się język Kotlin, a które mniej lub bardziej ułatwiają życie programisty.
1. Walka z nullami
W Kotlinie w bardzo łatwy sposób pozbyto się NPE, czyli jednego chyba z najczęściej występujących i najbardziej kosztownych wyjątków na świecie.
Rozwiązanie: Java zwykły nullcheck albo Optional
Przykład:
If(value != null){
value.wykonaj()
}
Rozwiązanie: Kotlin operator ? który zastępuje nullchecka
Przykład:
value?.wykonaj()
2. Wartości domyśle
Kotlin daje nam łatwą możliwość ustawienia wartości domyślnych w parametrach funkcji. Natomiast w Javie musimy stosować, albo wzorzec Buildera albo przeciążać operatory.
Rozwiązanie: Java
UserBuilder.setName(“Grzegorz”).setSurname(Brzeczyszczykiewicz).setAge(24).build()
albo
public User(String name, String surname, Integer age) {
this.name = name;
this.surname = surname;
this.age = age;
}
public User(String name, String surname) {
this (name, surname, 24);
}
Rozwiązanie: Kotlin
class User(var name: String = "", var surname: String = "",var age=0)
Wykorzystujemy to w kodzie w taki sposób
User() , User(name= “Grzegorz”), itp.
3. Brak seterów i getterów
Przyjęło się że w Javie wartości pól ustawia się poprzez gettery, a pobiera poprzez settery. Jednak często to prowadzi do sytuacji ze mamy jakaś klasę, która przechowuje dane i składa się tylko z “pustych” setterów i gettrów. W Kotlinie gettery i settery są generowane automatycznie.
Przykład: Java
public class User{
private String name = ””
public void setName(String name){
this.name = name;
}
public String getName(){
return name
}
}
Przykład: Kotlin
class User(){
var name : String = ””
}
4. Specjalna klasa do przechowywania danych
W Javie nie ma żadnej specjalnej klasy do przechowywania danych. Powoduje to oczywiście pewne problemy np. z porównywaniem obiektów, które zawierają takie same dane albo nawet z toString(). W Kotlinie istnieje specjalny typ klasy, który jest dedykowany danym, a mianowicie data.
Przykład:
data class User(val name : String, val surname : String, val age : String)
Różnica między data class, a zwykłą klasa jest dość prosta, polega ona na tym ze Kotlin nadpisuje nam takie metody jak equals albo toString.
5. Funkcje rozszerzające
Często zdarza się sytuacja, że jakaś klasa, do której nie mamy dostępu (bo np. pochodzi z innej biblioteki) nie posiada metod, które są dla nas bardzo istotne. Często w takiej sytuacji piszemy klasy Utils. Mają nam pomóc w uzyskaniu tego, czego potrzebujemy. Problem polega na tym, że ktoś kto korzysta z owoców naszej pracy musi wiedzieć, że taka klasa istnieje i nie trzeba jej pisać od nowa. Oczywiście pomijam fakt, że jest to po prostu brzydkie. W Kotlinie, aby rozwiązać ten problem, zostały dodane funkcje rozszerzające.
Przykład: Java
public class MapUtils{
public String rotateMap(map:Map){
...rotate map
}
}
Użycie: MapUtils().rotateMap(map)
Przykład: Kotlin
fun Map.rotateMap(){
...rotate map
}
Użycie: Map.rotateMap()
6. Łatwiejsza obsługa stringów
Ciężko sobie wyobrazić program, który nie komunikowałby się z użytkownikiem za pomocą słowa pisanego. Niestety w Javie praca na stringach jest dość trudna. Sklejenia stringów powoduje, że kod jest nieczytelny i zaśmiecony. W Kotlinie istnieje możliwość wstawienia wartości bezpośrednio w string.
Przykład: Java
public String getMyLovelyString(){
return “name ”+ name + “ surname ”+ surname “ age ” + age
}
Przykład: Kotlin
fun getMyLovelyString() : String{
return “name $name surname $surname age $age”
}
Oczywiście takich udogodnień jest dużo, dużo więcej. Nawet, te które przedstawiłem powyżej są o wiele bardziej skomplikowane np. Z tym NPE to nie do końca prawda ;). Ale czas na podsumowanie.
Podsumowując, Kotlin jest tym, czym Java będzie najprawdopodobniej za kilka iteracji. Czyli językiem szybkim, bezpiecznym, stabilnym, a co najważniejsze – łatwym w użyciu i po prostu bardziej czytelnym.
Zostaw komentarz