marko devcic

  • github:
    deva666
  • email:
    madevcic {at} gmail.com

Kotlin to the rescue

Posted on 6 January 2017

If you are doing any kind of Android development, you are stuck on Java 7. Most importantly, that means no lambdas and higher order functions. And it may be some time until we get full Java 8 support on Android.
But, luckily for us, guys at JetBrains (makers of IntelliJ) didn’t like some features in Java so they decided to roll out their own language that compiles to JVM bytecode.
The language called Kotlin.
I’ve been using it every day for more than 6 months, and I can say that I like it. I like it a lot.
It’s stable, can be used alongside existing Java code and support for it in IntelliJ and Android Studio is excellent.

I want to go over some features of the language that make JVM/Android development more fun.
Basic knowledge of Kotlin and Java is required.


Reified generics

Java’s generics are implemented with Type erasure. A process where all generic type information is intentionally dropped during compilation. Yes, it ensures backward compatibility, but sometimes it can be a real pain. How many times you wished you could do something like this:
public <T> void instance() {
	Class<T> clazz = T.class; // compiler error
	return clazz.newInstance();
}
In Kotlin mark the generic parameter with reified keyword and you can access its type during runtime!
inline <reified T> instance() : T where T : Any{
	return T::class.java.newInstance();
}

Lambdas and Higher order functions

Functions are first class citizens in Kotlin. This goes hand in hand with lambdas.
You can declare a function type variable, functions can accept other functions as arguments and they can also return functions.
Example, a function variable that accepts an integer as argument and returns a boolean value. The variable is initialized with a lambda function.
val isEven : (Int) -> Boolean = { i -> i % 2 == 0 }
Functions can also return other functions
fun createHigherThanPredicate(value: Int): (Int) -> Boolean {
        return { i -> i > value }
}

Extension functions

Taken from C#, they enable you to add new functions to existing classes. Not only can you write extensions for your code, the standard library comes with loads of Iterable extension methods. Just one example will make it clear. In Java, if you want to get the first item from a collection that satisfies some boolean condition, the code looks something like this:
for (Person p : persons){
	if (p.getName().equals(“John”)) {
	return p;
   }
   return null;
}
Kotlin standard library has an extension that does it for you:
persons.firstOrNull { p -> p.name == “John” }

Null safety

Yes nullable types are needed, but how many times have you’ve been hit with NullPointerException.
Kotlin solves this problem perfectly.
You want a nullable type? Declare it as nullable!
var someString = null  //compiler error

var otherString = “fooBar”
otherString = null //compiler error

var nullableString: String? = null //this is legal
Kotlin has an operator that enables you to do inline null checks. Operator called elvis, ?:
If anything on the left side of the elvis operator is null, the value on the right side will be returned.
nullableString?.length() ?: -1 //if nullableString is null, -1 is returned

Type inference

For any strongly typed language with static type checking these days this is a must have.
var someString = “fooBar” // don’t have to declare the type, compiler knows it is a string
someString = 1 //compiler error
myButton.setOnClickListener { v -> v.clearFocus() } // compiler knows that v inside lambda is of type View 

No checked exceptions

Some people like them and some don’t. I’m in the latter group.
Most languages don’t have them and it looks like guys at JetBrains also think that the language shouldn’t tell you how you write your code.

String templates

You can insert code inside string literals.
val person = Person(“John”)
val personName = “This person has a name: ${person.name}”

No covariant arrays

Arrays in Kotlin are invariant. In Java they are covariant.
Making arrays covariant at the time (before generics were introduced) was a good idea, but you can easily make errors that compiler won’t catch.
For example, create an array of strings and an array of objects. Assign the strings to objects. Add an integer to objects and you get ArrayStoreException during runtime.


Even though there are still some areas of the language that are still work in progress, like annotation processing not working (should be fixed in v1.04) and being really slow, I'd highly recommend it.

Happy coding!