Kiedy Java developer po raz pierwszy słyszy o Kotlinie, reakcja jest zazwyczaj jedna z dwóch.

Pierwsza: „O, ciekawe — powinienem to sprawdzić."

Druga: „Po co? Java działa. Pensja wpływa. Wszystko gra."

Java vs Kotlin: uczciwe porównanie - 1

Obie reakcje są zrozumiałe. Ktoś spędził lata na nauce Javy, dobrze ją zna, nie chce zaczynać od nowa — to całkowicie rozsądne.

Ale jest trzecia reakcja, o której nikt nie mówi: „To język, na który nasz CTO nas przenosi w przyszłym kwartale."

Dla wszystkich trzech przypadków — rozłóżmy to uczciwie. Bez wypowiadania wojny i bez entuzjastycznego ewangelizmu.

Skąd wziął się Kotlin — i co ma z tym wspólnego Oracle

Java pojawiła się w 1995 roku. Trzydzieści lat — ogromny ekosystem, Spring, Hibernate, Maven, Gradle, miliony developerów, góry dokumentacji. To nie umiera. To żyje, rozwija się i czuje się znakomicie.

Kotlin został wydany w 2016 roku. JetBrains stworzył go dla siebie — zmęczyli się boilerplatem podczas rozwijania IntelliJ IDEA. Kluczowa decyzja: Kotlin kompiluje się do tego samego bytekodu JVM co Java. Działają razem w tym samym projekcie. Żadnej wojny — po prostu różne narzędzia.

W 2017 roku Google ogłosił Kotlin oficjalnym językiem dla Androida.

Oficjalnie — bo developerzy o to prosili i język jest wygodniejszy. Prawda.

Ale jest kontekst, który warto znać.

Od 2010 roku Google toczył spór prawny z Oracle o użycie Java API w Androidzie. Oracle żądał 8,8 miliarda dolarów — tyle, że nawet Google poczuł się nieswojo. Sprawa trafiła do Sądu Najwyższego USA i zakończyła się dopiero w 2021 roku wygraną Google. Jedenaście lat prawnej niepewności.

Kotlin od JetBrains jest open source i bez ryzyka licencyjnego. Google nigdy oficjalnie nie powiązał tej decyzji z procesem sądowym. Ale jak mówią — korelacja to nie przyczynowość, dopóki jakoś nią nie jest.

Plusem całej sytuacji jest to, że konkurencja skłoniła Oracle do aktywniejszego rozwijania Javy. Records, sealed classy, pattern matching w nowszych wersjach — między innymi dlatego, że trzeba było dotrzymać kroku Kotlinowi. Czy Oracle tego chciał, czy nie — wszyscy developerzy na JVM na tym zyskali.

Składnia: porównanie na żywo

Jedno zadanie — przefiltruj listę użytkowników, którzy mają co najmniej 18 lat.

// Java
List<User> adults = users.stream()
    .filter(u -> u.getAge() >= 18)
    .collect(Collectors.toList());

// Kotlin
val adults = users.filter { it.age >= 18 }

Cztery linie kontra jedna. W większości codziennych zadań Kotlin jest zauważalnie bardziej zwięzły.

Uczciwie mówiąc: w Javie wszystko jest jawne. Czytasz kod i wiesz dokładnie, co się dzieje. W Kotlinie niektóre konstrukcje wymagają przyzwyczajenia. Dla początkujących Java jest pod tym względem faktycznie bardziej przejrzysta.

Ale jeśli spędziłeś kilka lat w Javie i piszesz Collectors.toList() na autopilocie — może to już nie jest „jawność", tylko pamięć mięśniowa.

Null-safety: największa różnica

Tony Hoare wynalazł null w 1965 roku i później publicznie nazwał to swoim „błędem wartym miliard dolarów". Rzadki przypadek, gdy autor sam przyznał się do buga. NullPointerException kosztował branżę od tamtej pory znacznie więcej — ale kto liczy.

// Java
String name = null;    // Kompilator milczy
name.length();         // NPE w runtime. Zazwyczaj w piątkowy wieczór.
                       // Czasem podczas live demo u klienta.

// Kotlin
var name: String = null   // Błąd kompilacji. Od razu. Przed uruchomieniem.

var name: String? = null  // Jawnie nullable — teraz okej
name?.length              // Jeśli null — zwróci null, nie padnie
name?.length ?: 0         // Jeśli null — zwróci 0

Java 8 wprowadziła Optional jako częściowe rozwiązanie. Pomaga, ale nie jest używana wszędzie — i NPE nadal się zdarzają.

W Kotlinie null-safety jest wbudowana w system typów. Kompilator nie przepuści kodu, gdzie możesz złapać NPE bez jawnego na to zezwolenia. Jak surowy code reviewer — tylko bez komentarzy „czy sprawdziłeś tu na nulla?"

Boilerplate: data class kontra POJO

Prosty model danych — użytkownik z trzema polami.

// Java
public class User {
    private final String name;
    private final int age;
    private final String email;

    public User(String name, int age, String email) {
        this.name = name; this.age = age; this.email = email;
    }

    public String getName() { return name; }
    public int getAge() { return age; }
    public String getEmail() { return email; }

    @Override public boolean equals(Object o) { ... }
    @Override public int hashCode() { ... }
    @Override public String toString() { ... }
}

40–50 linii. Można użyć Lomboka — ale to dodatkowa zależność, konfiguracja IDE, a potem ktoś w zespole nieuchronnie mówi „u mnie Lombok nie działa".

// Kotlin
data class User(val name: String, val age: Int, val email: String)

Jedna linia. Kompilator generuje equals(), hashCode(), toString() — i dodatkowo copy():

val anna = User("Anna", 30, "anna@example.com")
val olderAnna = anna.copy(age = 31)  // Kopia z jednym zmienionym polem

copy() — czegoś takiego Java nie ma z pudełka. Dlaczego — dobre pytanie, na które Java nadal nie odpowiedziała.

Coroutines vs wątki

W Javie praca asynchroniczna to Thread, ExecutorService, CompletableFuture. Potężne. Ale kod szybko staje się łańcuchem, którego nawet autor nie rozczyta miesiąc później.

// Java
CompletableFuture.supplyAsync(() -> fetchUser(id))
    .thenApply(user -> processUser(user))
    .thenAccept(result -> sendResult(result))
    .exceptionally(e -> { handleError(e); return null; });

// Kotlin
suspend fun loadAndProcess(id: Int) {
    val user = fetchUser(id)
    val result = processUser(user)
    sendResult(result)
}

Kotlinowy kod czyta się jak zwykła synchroniczna logika — z góry na dół, bez zagnieżdżeń. I nadal działa asynchronicznie, nie blokując żadnych wątków.

Ważna uwaga: coroutines nie zastępują wątków. Są idealne dla zadań I/O-intensywnych — tysiące lekkich operacji bez tworzenia tysięcy prawdziwych wątków systemowych. Do ciężkich obliczeń CPU nadal potrzebujesz wątków. Tu coroutines nie pomogą.

Interoperacyjność — argument, o którym często się zapomina

Kotlin i Java działają w tym samym projekcie. Jednocześnie.

Pliki Javowe i Kotlinowe leżą obok siebie. Wywołują wzajemnie swoje metody. Kompilują się do tego samego JAR-a. Używają tych samych bibliotek.

Co oznacza: to nie jest wszystko albo nic. Możesz zacząć pisać nowe moduły w Kotlinie, nie dotykając istniejącego kodu. Większość zespołów robi dokładnie tak — stopniowo, bez bohaterstwa, bez nocnych dyżurów.

Gdzie Java naprawdę wygrywa

Dokumentacja i Stack Overflow. Przez dekady powstawała dokumentacja Javy. Każde pytanie — jest już sto odpowiedzi na Stack Overflow, z których jedna jest prawidłowa. Dystans do Kotlina się zmniejsza, ale nadal istnieje.

Projekty legacy. System zbudowany 15 lat temu na Java 8, który działa — nie ruszaj. Żadnego zysku, tylko ryzyko.

Środowiska korporacyjne. W dużych organizacjach stosy technologiczne zmieniają się powoli i boleśnie. Java jest znajoma dla wszystkich: zespołu, audytorów, działu bezpieczeństwa. I dla nowego developera, który dołączy za rok i zapyta „a czemu używamy Kotlina?"

Gdzie Kotlin naprawdę wygrywa

Android. Sprawa zamknięta. Google oficjalnie rekomenduje Kotlin, wszystkie nowe API są pod niego pisane, a Jetpack Compose jest tylko w Kotlinie. Zaczynanie nowego projektu androidowego w Javie w 2026 roku wywołałoby u kolegów taką samą reakcję jak przyjazd do pracy konno.

Nowe serwisy backendowe. Mniej kodu, wbudowana null-safety, coroutines — sensowny wybór dla nowych projektów.

Kotlin Multiplatform. Wspólna logika biznesowa dla iOS, Androida i webu z jednej bazy kodu. Netflix, Philips i inne duże firmy już tego używają.

Czy naprawdę trzeba wybierać?

Nie.

To nie jest „Java albo Kotlin". To „tylko Java, albo Java plus Kotlin".

Java zostaje — jej ekosystem jest ogromny i nikt nie przepisuje działającego kodu dla nowego języka. Kotlin rośnie — szczególnie w mobile i nowych projektach backendowych.

Znanie obu oznacza więcej możliwości. Bez utraty czegokolwiek, co już masz.

Dla Java developera przesiadka zajmuje tygodnie. Ta sama JVM, ta sama logika. Jedyne, co musisz zrobić, to zacząć.

Jeśli chcesz solidnie wejść w Kotlin — mamy kurs. 62 poziomy, ponad 1100 zadań, 3 projekty do portfolio. Pierwszy poziom jest bezpłatny.

codegym.cc/pl/courses/kotlin

Czytaj dalej