Kotlin megjelenése óta több év telt el, és ez jól sikerült. Mivel kifejezetten a Java helyettesítésére hozták létre, a Kotlint természetesen sok szempontból összehasonlították a Java-val.
Annak érdekében, hogy eldönthessem, melyik nyelvet érdemes választania, összehasonlítom az egyes nyelvek néhány főbb jellemzőjét, hogy kiválaszthassa a megtanulandó nyelvet.

Ez a 8 pont, amelyet ebben a cikkben tárgyalok:
- Szintaxis
- Lambda kifejezések
- Semmi kezelés
- Modellosztályok
- Globális változók
- Egyidejűség
- Bővítési funkciók
- Közösség
Szintaxis összehasonlítás
Először is végezzünk néhány alapszintaktikai összehasonlítást. Lehet, hogy sokan, akik ezt olvassátok, már tudnak valamilyen ismerettel a Java-ról és / vagy a Kotlinról, de az alábbiakban bemutatok egy alapvető példát, hogy közvetlenül összehasonlítsuk őket:
Jáva
public class HelloClass { public void FullName(String firstName, String lastName) { String fullName = firstName + " " + lastName; System.out.println("My name is : " + fullName); } public void Age() { int age = 21; System.out.println("My age is : " + age); } public static void main(String args[]) { HelloClass hello = new HelloClass(); hello.FullName("John","Doe"); hello.Age(); } }
Kotlin
class NameClass { fun FullName(firstName: String, lastName:String) { var fullName = "$firstName $lastName" println("My Name is : $fullName") } } fun Age() { var age : Int age = 21 println("My age is: $age") } fun main(args: Array) { NameClass().FullName("John","Doe") Age() }
A kód érzése nem annyira különbözik a módszerek és osztályok néhány apró szintaxis-változtatásától.
De az igazi különbség itt az, hogy Kotlin támogatja a típusú következtetéseket, ahol a változó típust nem kell deklarálni. Továbbá nincs szükségünk pontosvesszőkre ( ;
).
Megjegyezhetjük azt is, hogy Kotlin nem szigorúan érvényesíti az OOP-t, mint a Java, ahol mindent egy osztályon belül kell tartani. Vessen egy pillantást fun Age
, és fun main
a példa, ahol nem belsejében minden osztályban.
Kotlinnak általában kevesebb kódsora is van, míg a Java jobban ragaszkodik ahhoz a hagyományos megközelítéshez, hogy mindent verbuváljon.
A Kotlin egyik előnye a Java-val szemben a Kotlin rugalmassága - dönthet úgy, hogy mindent a hagyományos OOP megközelítéssel végez, vagy másképp is mehet.
Lambda kifejezések
Ha Java-ról és Kotlinról beszélünk, akkor természetesen a híres lambda kifejezésről is beszélnünk kell. Kotlin natív Lambda támogatással rendelkezik (és mindig is volt), míg a lambdát először a Java 8-ban vezették be.
Lássuk, hogyan néznek ki mindketten.
Jáva
//syntaxes parameter -> expression (parameter1, parameter2) -> { code } //sample usage ArrayList numbers = new ArrayList(); numbers.add(5); numbers.add(9); numbers.forEach( (n) -> { System.out.println(n); } );
Kotlin
//syntax { parameter1, parameter2 -> code } //sample usage max(strings, { a, b -> a.length < b.length })
A Java-ban a zárójelek engedékenyebbek: ha csak egy paraméter létezik, akkor nincs szükség zárójelekre. De Kotlinban mindig zárójelre van szükség. Összességében azonban a szintaxison kívül nincs sok különbség.
Véleményem szerint a lambda függvényeket nemigen fogják használni, eltekintve attól, hogy visszahívási módszerként használják őket. Annak ellenére, hogy a lambda funkcióknak sokkal több felhasználása van, az olvashatósági problémák miatt kevésbé kívánatos. Lerövidítik a kódot, de a kód későbbi kitalálása sokkal nehezebb lesz.
Ez csak preferencia kérdése, de szerintem hasznos, hogy Kotlin betartja a kötelező zárójeleket az olvashatóság elősegítése érdekében.
Semmi kezelés
Objektumorientált nyelvben a null típusú értékek mindig is problémát jelentettek. Ez a probléma Null Pointer Exception (NPE) formájában jelenik meg, amikor egy null érték tartalmát próbálja használni.
Mivel az NPE-k mindig is problémát jelentettek, a Java-nak és a Kotlinnak is megvan a maga módja a null objektumok kezelésére, amint azt alább bemutatom.
Jáva
Object object = objServ.getObject(); //traditional approach of null checking if(object!=null){ System.out.println(object.getValue()); } //Optional was introduced in Java 8 to further help with null values //Optional nullable will allow null object Optional objectOptional = Optional.ofNullable(objServ.getObject()); //Optional.of - throws NullPointerException if passed parameter is null Optional objectNotNull = Optional.of(anotherObj); if(objectOptional.isPresent()){ Object object = objectOptional.get(); System.out.println(object.getValue()); } System.out.println(objectNotNull.getValue());
Kotlin
//Kotlin uses null safety mechanism var a: String = "abc" // Regular initialization means non-null by default a = null // compilation error //allowing null only if it is set Nullable var b: String? = "abc" // can be set null b = null // ok print(b)
Amíg csak emlékszem, a Java a hagyományos nullellenőrzést alkalmazta, amely hajlamos emberi hibára. Ezután a Java 8 opcionális osztályokkal jelent meg, amelyek lehetővé teszik a robusztusabb nullellenőrzést, különösen az API / Server oldalról.
A Kotlin viszont null biztonsági változókat biztosít, ahol a változónak nullázhatónak kell lennie, ha az érték null lehet.
Még nem igazán használtam az opcionális osztályt, de a mechanizmus és a cél meglehetősen hasonlónak tűnik Kotlin null biztonságához. Mindkettő segít azonosítani, hogy mely változó lehet nulla, és segít abban, hogy a helyes ellenőrzés megvalósuljon.
Előfordulhat, hogy a kódban túl sok változó fekszik, és túl sok az ellenőrzéshez. De mindenhol hozzáadva az ellenőrzést, csúnya a kódalapunk, és ezt senki sem szereti, igaz?
Véleményem szerint azonban a Java opcionális használata kissé rendetlennek tűnik az ellenőrzésekhez hozzáadandó kód mennyisége miatt. Eközben Kotlinban csak kis mennyiségű kódot adhat hozzá, hogy semmit sem ellenőrizzen.
Modellosztály
Vannak, akik ezt Entity osztályként is emlegethetik. Az alábbiakban láthatja, hogyan használják mindkét osztályt mint osztályosztályok az egyes nyelveken.
Jáva
public class Student { private String name; private Integer age; // Default constructor public Student() { } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setAge(Integer age) { this.age = age; } public Integer getAge() { return age; } }
Kotlin
//Kotlin data class data class Student(var name: String = "", var age: Int = 0) //Usage var student: Student = Student("John Doe", 21)
In Java, properties are declared as private, following the practice of encapsulation. When accessing these properties, Java uses Getters and Setters, along with the isEqual or toString methods when needed.
On the Kotlin side, data classes are introduced for the special purpose of model classes. Data classes allow properties to be directly accessed. They also provide several in-built utility methods such as equals(), toString() and copy().
For me, data classes are one of the best things Kotlin offers. They aim to reduce the amount of the boilerplate code you need for regular model classes, and they do a really good job of that.

Global Variables
Sometimes your code might need a variable needs to be accessed everywhere in your code base. This is what global variables are used for. Kotlin and Java each have their own ways of handling this.
Java
public class SomeClass { public static int globalNumber = 10; } //can be called without initializing the class SomeClass.globalNumber;
Kotlin
class SomeClass { companion object { val globalNumber = 10 } } //called exactly the same like usual SomeClass.globalNumber
Some of you might already be familiar with the static keyword here since it's also used in some other language like C++. It's initialized at the start of a program's execution, and is used by Java to provide global variables since it is not contained as an Object. This means it can be accessed anywhere without initializing the class as an object.
Kotlin is using quite a different approach here: it removes the static keyword and replaces it with a companion object which is pretty similar to a singleton. It let's you implement fancy features such as extensions and interfacing.
The lack of the static keyword in Kotlin was actually quite surprising for me. You could argue that using the static keyword might not be a good practice because of its nature and because it's difficult to test. And sure, the Kotlin companion object can easily replace it.
Even then, using static for global variable should be simple enough. If we are careful with it and don't make it a habit of making every single thing global, we should be good.
The companion object might also give us some flexibility with interfacing and such, but how often will we ever be interfacing singleton classes?
I think static keywords help us keep things short and clean for global variables.
Concurrency
Nowadays, concurrency is a hot topic. Sometimes the ability of a programming language to run several jobs concurrently might help you decide if that will be your language of choice.
Let's take a look at how both languages approach this.
Java
// Java code for thread creation by extending // the Thread class class MultithreadingDemo extends Thread { public void run() { try { // Displaying the thread that is running System.out.println ("Thread " + Thread.currentThread().getId() + " is running"); } catch (Exception e) { // Throwing an exception System.out.println ("Exception is caught"); } } } // Main Class public class Multithread { public static void main(String[] args) { int n = 8; // Number of threads for (int i=0; i
Kotlin
for (i in 1..1000) GlobalScope.launch { println(i) }
Java mostly uses threads to support concurrency. In Java, making a thread requires you to make a class that extends to the in-built Java thread class. The rest of its usage should be pretty straightforward.
While threads are also available in Kotlin, you should instead use its coroutines. Coroutines are basically light-weight threads that excel in short non-blocking tasks.
Concurrency has always been a hard concept to grasp (and also, to test). Threading has been used for a long time and some people might already been comfortable with that.
Coroutines have become more popular lately with languages like Kotlin and Go (Go similarly has goroutines). The concept differs slightly from traditional threads – coroutines are sequential while threads can work in parallel.
Trying out coroutines, though, should be pretty easy since Kotlin does a very good job explaining them in their docs. And one bonus for Kotlin over Java is the amount of boilerplate code that can be removed in Kotlin.
Extension Functions
You might be wondering why I'm bringing these up since Java itself doesn't even have this feature.
But I can't help but mention it, because extension functions are a very useful feature that was introduced in Kotlin.
fun Int.plusOne(): Int { return this + 1 } fun main(args: Array) { var number = 1 var result = number.plusOne() println("Result is: $result") }
They allow a class to have new functionality without extending it into the class or using any of the fancy Design Patterns. It even lets you to add functionality to Kotlin variable classes.
You can practically say goodbye to those lib method that need you to pass everything inside your parameters.
Community
Last but not least, let's talk about something non-technical. First, let's take a look at this survey showing top commonly used programming languages in 2020.

We can see that Java is one of the most commonly used languages. And while Kotlin is still rising a lot in popularity, the Java community still remains several times larger than Kotlin and it will probably not change anytime soon.
So what does that matter then? Actually it does matter, a lot. With the amount of people in the Java community, it's much easier to find references and get help when you need it, both on the Internet and in the real world.
Many companies are also still using Java as their base and it might not change anytime soon even with Kotlin's interoperability with Java. And usually, doing a migration just doesn't serve any business purpose unless the company has really really important reasons for it.
Wrapping up
For those just scrolling for the summary, here's what we discussed:
- Syntax: the patterns don't differ that much aside from slight syntax differences, but Kotlin is more flexible in several aspects.
- Lambda Expressions: the syntax is almost the same, but Kotlin uses curly brackets to help readability.
- Null Handling: Java uses a class to help with null handling while Kotlin uses in-built null safety variables.
- Model Classes: Java uses classes with private variables and setter / getter while Kotlin supports it with data classes.
- Global Variables: Java uses the static keyword while Kotlin uses something akin to sub-classes.
- Concurrency: Java uses multi-threading whereas Kotlin uses coroutines (which are generally lighter).
- Extension Functions: a new feature introduced by Kotlin to easily give functionality into classes without extending it.
- Community: Java still reigns supreme in the community aspect which makes it easier to learn and get help.

There are many more features we could compare between Java and Kotlin. But what I've discussed here are, in my opinion, some of the most important.
I think Kotlin is well worth picking up at the moment. From the development side it helps you remove long boilerplate code and keep everything clean and short. If you are already a Java programmer, learning Kotlin shouldn't be too hard and it's okay to take your time at it.
Thanks for reading! I hope that this article will help you decide which programming language you should pick, Java or Kotlin. And for anything that I'm missing, feel free to leave feedback for me as it will be very much appreciated.