Kotlin - The next generation of Java
Introduction
I’m a Java developer for more than seven years and I have been always fine with it. Since a few years I’m also developing Android Apps and this community is hyping the language Kotlin. I read a lot about Kotlin, so I started to check out what this hype is about. After writing my first App in Kotlin, I must admit that Kotlin is the next generation of Java. Due to my revelation about Kotlin, I would like to share my thoughts why I am thinking that way.
Spoiler alert: I saved a lot of boilerplate code without having any disadvantages, e.g. bad IDE support, worse debugging nor high effort to configure my first Kotlin App. With AndroidStudio or IntelliJ, I can even copy code from a Java class and paste it to a Kotlin class and I get Kotlin code. Nice!
Keyfacts about Kotlin
- Like Java, it’s an object oriented language and statically-typed
- Kotlin classes are compiled to Java byte code
- I can use all my favorite Java libraries
- It’s not limited to Android
Get rid of stupid characters
I like to improve a given Java snippet by Kotlin. I gonna show up the syntactic sugar step by step, so that you are not lost at the good parts.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class StupidCharacters extends SuperStupid { private ArrayList<String> list = new ArrayList<>(); public StupidCharacters(String string) { super(string); } public String getFirst() { return list.get(0); } public void addString(String string) { list.add(string); } } |
No need to write ;, new or void. Write : instead of extends. Which visibility modifier is mostly used in Java? Public! So by default, defining something without a modifier in Kotlin means public!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class StupidCharacters : SuperStupid { private ArrayList<String> list = ArrayList<>() StupidCharacters(String string) { super(string) } String getFirst() { return list.get(0) } addString(String string) { list.add(string) } } |
Don’t repeat yourself by mentioning ArrayList in the declaration and initialization. I gonna tell you later what val is about.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class StupidCharacters : SuperStupid { private val list = ArrayList<String>() StupidCharacters(String string) { super(string) } String getFirst() { return list.get(0) } addString(String string) { list.add(string) } } |
Turn the return type of a method around. Declare the parameter name before the type and separate these with :. We need to write fun before the method name. To make this clear: fun is the keyword for functions. We do not write fun just for fun.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class StupidCharacters : SuperStupid { private val list = ArrayList<String>() StupidCharacters(string: String) { super(string) } fun getFirst(): String { return list.get(0) } fun addString(string: String) { list.add(string) } } |
Every Java class has a constructor. Sometimes you don’t see the default constructor, because it will be generated, but there is at least one. So Kotlin has a nice syntax for that. You declare the first constructor behind the class name and you should define which parent constructor you like to override. Notice that you don’t repeat the class name and yes you can have more than one constructor in Kotlin, but this is another topic.
1 2 3 4 5 6 7 8 9 10 11 12 |
class StupidCharacters(string: String) : SuperStupid(string) { private val list = ArrayList<String>() fun getFirst(): String { return list.get(0) } fun addString(string: String) { list.add(string) } } |
For the first time, we have valid Kotlin code! Last but not least, for single line method you are able to write the complete method in one line and you can remove the return type. The return type is the type of the called method.
1 2 3 4 5 6 7 8 |
class StupidCharacters(string: String) : SuperStupid(string) { private val list = ArrayList<String>() fun getFirst() = list.get(0) fun addString(string: String) = list.add(string) } |
What happens with the code? From 16 lines Java, we get 8 lines Kotlin code. This little numbers game shows, that we need less code for the same functionality. Now we can go to the next level.
Why should I write tests for getter and setter?
Hopefully, nobody writes tests for that. Why? They are more or less boilerplate code, so many developers ignore them. Good IDEs are generating this code for us. No reason to test them. I go even one step further and ask the heretic question: Why to write them? You do not write getters and setters in Kotlin. The property has the ability to read it val or to read and write it var. If you are calling a Java getter method inside Kotlin, you are able to write it like you wanna access a property. The compiler gives you feedback that you can’t set a val.
1 2 3 4 5 6 7 8 9 10 11 |
class GetSet(var set: Boolean, val get: Boolean) { fun doSomething() { val getSet = GetSet(true, false) val set = getSet.set val get = getSet.get getSet.set = false getSet.get = false // compile error } } |
What is the best singleton implementation?
One of the simplest singleton implementation might be this one.
1 2 3 4 5 6 7 8 9 10 11 |
public class EagerSingleton { private static EagerSingleton instance = new EagerSingleton(); private EagerSingleton() { } public static EagerSingleton getInstance() { return instance; } } |
But if you are using this implementation what happens on the application start? All singletons will be initialized. This can consume valuable runtime and memory even when they are never used. So a lazy singleton would be a better solution.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class LazySingleton { private static LazySingleton instance; private LazySingleton() { } public static LazySingleton getInstance() { synchronized (LazySingleton.class) { if (instance == null) { instance = new LazySingleton(); } } return instance; } } |
Better solution, but good enough? Not really. The check if is inside the synchronized block and under load you have a bottleneck. Next try.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class LazySingleton { private static volatile LazySingleton instance; private LazySingleton() { } public static LazySingleton getInstance() { if (instance == null) { synchronized (LazySingleton.class) { if (instance == null) { instance = new LazySingleton(); } } } return instance; } } |
More code, better solution. My personal favorite solution is the singleton holder pattern. It’s a property of the Java classloader, that this will work. The inner class is loaded only when it is called.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class LazySingleton { private LazySingleton() { } public static LazySingleton getInstance() { return LazySingletonHolder.INSTANCE; } private static class LazySingletonHolder { private static final LazySingleton INSTANCE = new LazySingleton(); } } |
Over the years I have discussed this topic with many developers and I do not know how many hours I have spent with it. For the JEE developers, yes I know that you have an annotation for that. In Spring you can define the scope. So lets see how many code do I need in Kotlin. Firstly, we start with a normal class.
1 |
class LazySingleton |
Yes it’s valid Kotlin code. Remove the word class and write object.
1 |
object LazySingleton |
LazySingleton is now an object, actually one object. No discussions about singletons anymore, no frameworks. The language has the power! By the way, it’s lazy.
Who needs builders?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class NoBuilder { public boolean one, two, three, four, five; public NoBuilder(boolean one, boolean two, boolean three, boolean four, boolean five) { this.one = one; this.two = two; this.three = three; this.four = four; this.five = five; } public static NoBuilder create() { return new NoBuilder(true, true, false, true, true); } } |
Imagine you have a constructor with many parameters. Sometimes I don’t know what was the third one? The solution in Java is to use builders.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
public class Builder { private final NoBuilder noBuilder = new NoBuilder(); public Builder withOne(boolean one) { noBuilder.one = one; return this; } public Builder withTwo(boolean two) { noBuilder.two = two; return this; } public Builder withThree(boolean three) { noBuilder.three = three; return this; } public Builder withFour(boolean four) { noBuilder.four = four; return this; } public Builder withFive(boolean five) { noBuilder.five = five; return this; } public NoBuilder build() { return this.noBuilder; } public static NoBuilder create() { return new Builder().withOne(true) .withTwo(true) .withThree(false) .withFour(true) .withFive(true) .build(); } } |
Now we are able to see the value of each parameter. For this benefit we need to write a lot of code. Let’s take a look on the Kotlin side.
1 2 3 4 5 6 7 8 9 10 11 12 |
class Builder(var one: Boolean = false, var two: Boolean = false, var three: Boolean = false, var four: Boolean = false, var five: Boolean = false) { fun create() = Builder(true, true, false, true, true) } |
It seems that we have the same problem, right? Not really. In Kotlin you are able to write the parameter label in front of the value. With labeled parameters you can also change the order of them and with defined default values we can leave off parameters.
1 2 3 4 5 6 7 8 9 10 |
class Builder(var one: Boolean = false, var two: Boolean = false, var three: Boolean = false, var four: Boolean = false, var five: Boolean = false) { fun create() = Builder(four = true, three = false, five = true) } |
Who likes to write delegation methods?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class ListDecorator<T>(val list: List<T> = ArrayList()) : List<T> by list { var count = 0 override val size: Int get() { count++ return list.size } fun doSomething() { val list = ListDecorator<String>() list.size list.count } } |
By using the keyword by you are able to delegate all methods of an interface to an object and you can override methods. A simple solution to implement the decorator pattern.
Do you like optionals in Java?
To be honest, I hate optionals until I’ve seen it in Kotlin.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class Optionals { public Optional<String> getOptional() { int randomInt = new Random().nextInt() % 3; if (randomInt == 0) { return Optional.of("value"); } else if (randomInt == 1) { return Optional.empty(); } else { return null; } } public void doSomething() { System.out.println(getOptional().orElseGet(() -> "no value").trim()); } } |
In Java you need to wrap objects and thereby more code. This object can be null and the compiler ignores the error.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Optionals { fun getOptional(): String? { val randomInt = Random().nextInt() % 3 if (randomInt == 0) { return "value" } else if (randomInt == 1) { return null } else { return null } } fun doSomething() { System.out.println((getOptional() ?: "no value").trim()) } } |
Add ? after a parameter or a return type to mark the value as optional. Without ? I’m not able to return null. No wrapping of objects needed and it’s save at compile time.
Wrapping a framework class is no fun!
Sometime you get to the point where you would like to add functions to a framework class. The solution in Java is wrapping it or creating a util class. In Kotlin, we write extension functions.
1 2 3 4 5 6 7 8 |
class Extension { fun String.addRandom() = this + UUID.randomUUID() fun doSomething() { "value".addRandom() } } |
Have you seen a wrong written equals, hashCode or toString method?
I’m sure you have. So let’s see what Kotlin can do for us. For sure, we can use Guava or Apache Commons and their builders to write this methods. Maybe there is something like Lombok integrated in the Kotlin language generating these methods? No, much better! This isn’t necessary because only the keyword data is required in front of your class.
1 2 3 4 5 6 |
data class PetrolStation(val uuid: String, val latitude: Double, val longitude: Double, val brand: String, val closed: Boolean, val address: Address) |
Last but not least, do you like it?
Hopefully, I inspired you to try Kotlin and you can make your own experiences. If so, Kotlin has plenty more stuff to discover, like inner classes, delegated properties, sealed classes, ranges, inline functions, control flow, type aliases, destructuring declarations, and so on. Just click here to check out more benefits of Kotlin.
Recent posts






Comment article