It is easy to fall in love with Kotlin. I would like to tell you about 10 Kotlin features I consider to be the best ones. I will also describe each of them in detail and explain why they made it to the top 10.
Kotlin – Top 10 Features You’ll Love
1. Null Safety
Kotlin is null safety language:
An address and telephone cannot be null in this example – an error occurs at compile time if you wish to set their value as null:
You need to say explicitly that a variable is nullable in order to be able to assign null to it. This could be done via “?” inserted right after the variable type (see an example of variable email above).
Your code could fail at compile-time whenever an NPE is thrown at run-time:
In order to solve a compilation error of
x.length, you can use if-statement:
The better way of achieving the same is via “safe calls in Kotlin” which returns the value of the call if the caller is not null, otherwise null returns.
You can work with nullable types more effectively by using the “Elvis Operator”.
In this case if x is not null its length will be used, otherwise -1 is used (as it is a default value).
2. Data Class
When you are creating business logic, persistent layer etc., you are creating domain objects, classes that do nothing but hold data (POJOs)… For instance, you must create Customer class which holds data about the customer’s id, name, and email.
In Kotlin a class can be marked as data class:
The Kotlin compiler will do all of this for you:
- generate functions:
copy()function (see more about this function below)
- componentN() functions
Sometimes you need to copy an object to a new one with different values of your
variables. This is what the
copy() function is for:
3. Extension Functions
Kotlin allows us to extend the functionality of existing classes without inheriting from them.
capitalize() is an extension function of the
String class. Inside the extension function, you access the object on which it was called using the keyword “this”.
Extensions do not modify classes they extend and are resolved statically.
Thanks to extensions, function code in projects where I’m using Kotlin is much cleaner. I do not have
xxUtils(.java) classes anymore.
Conversion to JSON could be a good example for using extension functions. Let’s demonstrate it on a very simple example that adds extension function to all “objects” in Kotlin. (
java.lang.Object are different types, but in runtime, they are represented with the same
4. Smart Cast
This is one of my favorite features as it makes my life much easier.
How often have you already casted objects? How often did you find out afterwards that it was actually redundant?
For example, if you want to check Object which is an instance of
java.lang.String, in order to print size this text you need to check the type first and then cast the object to the String before getting access to the specific method from the String object. When I started using Kotlin I did not consider this to be anything special, but after a few days I realized I really miss this feature in Java.
The Kotlin compiler is really smart when it comes to casting. It will handle all redundant casts for you.
instanceof Java operator in Kotlin is called
is. You can see in the example above that in Kotlin you do not need to cast object inside of statement if you already checked it with an operator is. I did not consider those redundant casts in Java as something strange until I began using Kotlin.
When expressions represent another example of smart casts:
Smart cast together with when expression make code readable:
In the example above you can see how to check if the event which comes from event bus can be checked and cast to correct java object. I agree that in this case it does not look so bad in Java but in Kotlin you can sum it up into this code:
I may be wrong but from my point of view, Kotlin takes the cake.
5. Singleton (Object)
Another Kotlin feature which I like is the simplicity of defining “singleton”. Consider the following example of how singleton could be created in Java.
Now you can call i.e.
Kotlin has a feature to define a singleton in a very clever way. You can use a keyword object which allows you to define an object which exists only as a single instance.
6. Functional Programming
A combination of lambda expression and the Kotlin library makes our life easier when working with collections:
7. Type Inference
In Kotlin, you do not have to specify the type of each variable explicitly:
8. Default Arguments
In Java, you often have to duplicate code in order to define different variants of a method or a constructor:
You can simply remove all of this when you switch to Kotlin by using default arguments.
9. Named Arguments
Default arguments become more powerful in combination with named arguments. You can see for yourself in the example of creating an instance of our OperatorInfoInKotlin from the previous section:
Now back to Java.
Based on this Java code, you do not know which values are set without knowing the
new OperatorInfoInJava("Vaclav", false, false, "blabla");
In Kotlin you have higher-order functions, lambda expressions, operator overloading, lazy evaluation and lots of other useful methods for working with the collection.
Lets demonstrate it on simple tasks:
“What is the average age of employees in the company in Pilsen city?”
(code below is in Java 1.6, of course you could use stream in Java 1.8 and write the code through lambda in Java as well)
Extension functions and functional programming are very powerful and Kotlin has many useful extensions for working with collections.
You can implement the same example in Kotlin using the following steps.
In the first step, you filter and keep all employees which are from the Pilsen city (Czech Republic)
Which Kotlin features do you appreciate the most when working with it?