Blog post Technical

Kotlin - what's so special?

First Look

Kotlin is a statically typed JVM language. This Android programming language offers many features, including extensions, data classes, operator overloading, and functional concepts. The best thing for Kotlin is its interoperability with the most widely used programming language, Java. That makes it more favorable for Android application development. The Java files can be easily converted to Kotlin files, with .kt extension. All types defined in Kotlin can be used from within Java like any other type.

JetBrains developed the Kotlin language in the open from much of its development. Now we can see how the language evolves, based on the feedback of early adopters, and experienced developers can feel they got the right mix of features.

Kotlin is quite small, to people that already know a programming language, and is being compared to Java in the similar way that Swift has been compared to Objective-C. Kotlin has no version inflation, like Swift (from v1.2 jumped directly to v2.0). It is very clean, simple, clear and removes a lot of the redundant code from Java, and also adds some needed features that Java doesn’t yet support in Android.

Kotlin vs Java – differences

Like C#, Kotlin allows developers to define methods on a class, and not by writing them inside the class. This feature is very useful in keeping the actual classes small and easy to manipulate, or when a developer is working with a lot of library code that cannot be changed easily. Kotlin is quite easy to debug, and much more readable than Java.

Extension functions

Extension functions are a great feature, which originally appeared in C#, and a feature that’s currently missing in Java. Kotlin has extension functions and allow us to add behavior to a class without directly extending it. With an extension function, we can call a function from an object as if it were part of its class and add methods to classes without modifying their source code.

How does it work? We have an extension function for a String called clearWord, and call it kotlinString.clearWord(). In this case, clearWord() is not a member of String class, but it looks like it is. We just need to add the function to any file:

StringExtensions.kt

fun String.clearWord(): String {

// … e.g. remove whitespaces/unnecessary characters from string and return it

}

Higher-order functions

Higher-order function takes functions as parameters, or return a function. For example:

fun firstAndSecond(operation: (Int, Int) -> Int) {

val result = operation(1, 2)

println("The result is $result")

}

One major use case for this is callback functions. Our sample function makes a network call with two callbacks, for success and for error. In Kotlin, those would be two parameter functions, which can be stored in variables for later use, or created inside another function.

fun networkCall(onSuccess: (ResultType) -> Unit,

onError: (Throwable) -> Unit) {

try {

// … create and execute network request

onSuccess(myResult)

} catch(e: Throwable) {

onError(e)

}

}

Usage:

networkCall(result -> {

// use successful result

}, error -> {

// handle error

});

Immutability

State management could be a very big concern when developing multithreaded applications. In Kotlin, immutable values are preferred whenever possible, but type system distinguishes between mutable and immutable views over collections. If a variable is mutable, it can be changed by any thread and multiple sources that can access it. That can cause a problem, but if the data can never be changed, it can be accessed by multiple threads without error.

Variables are declared with the keywords var and val, and we can always specify a type explicitly. Java has similar functionality with the final keyword. In Kotlin, var defines one with a getter and setter, whereas val defines a property with a getter and a private setter, and it must be assigned in the constructor. This is not true immutability. If you have a val variable holding a mutable object, e.g. an ArrayList, the contents of the list can be changed, even though you cannot assign a new list to the same variable directly.

Lambdas

If a function is not declared, but passed immediately as an expression, we call it a lambda, or an anonymous function. Kotlin has functional programming support with the ability to do mapping, folding etc. over standard Java collections. For example:

val languageArray = arrayOf("Serbian", "Swahili", "Japanese", "German", "Spanish")

val selectedLang = languageArray

.filter { name -> name.startsWith("s", ignoreCase = true) }

//or: .filter { it.startsWith("s", ignoreCase = true) }

.sortedBy { name -> name.length }

.first()

Data classes

This feature is a very useful way to auto-generate JavaBean boilerplate, and a great time saver. We often find ourselves creating classes with only properties and fields. In Java, this can be very complex, with a get/set method for each field. For example, in Java we have:

public class Laptop {

private String name;

private int ram;

public Laptop(String name, int ram) {

this.name = name;

this.ram = ram;

}

public void setName(String name) {

this.name = name;

}

public String getName() {

return this.name;

}

public void setRam(int ram) {

this. ram = ram;

}

public int getRam() {

return this.ram;

}

}

And in Kotlin:

data class Laptop(var name: String, var ram: Int)

The compiler will generate getters, setters and everything we had to write in Java.

Null safety

All types are non-nullable by default and most sources of null references are eliminated. Kotlin lets the compiler systematically flag potential null pointer dereferences, and it won’t allow use of a non-initialized, non-nullable variable. When variables have to hold a null value, developers have to declare the type as nullable, adding a question mark after the type (similar to C#):

var nonNullable: String = "This string is non nullable" // needs to be initialized

var nullable: String?

Whenever we access a nullable variable, the compiler will enforce a null-check. This makes the code clearer by being explicit on what can and cannot be null and drastically reduces bugs, increasing code and product quality.

When accessing a nullable variable, you can check if it’s null in two ways. The first is a traditional if statement:

if (nullable != null) nullable.doStuff()

The second is the safe call operator:

nullable?.doStuff()

The safe call operator can be chained multiple times, making navigating the properties of a nullable object with other nullable objects much more concise than multiple null checks.

Usage of a non-nullable variable vs. a nullable variable with a safe call operator:

println(nonNullable.substring(0, 2)) // prints the first 2 characters

println(nullable?.substring(0, 2)) // prints the first 2 characters if the string is not null, else prints null

There may be some cases where a variable is nullable, but you, as a programmer, are sure that the variable can’t be null. For such cases, the !! operator makes an unsafe call to a nullable variable, assuming it holds a value. If it’s null, a NullPointerException will be thrown.

println(nullable!!.substring(0,2)) // prints the first 2 characters if the string is not null, crashes with a NullPointerException otherwise.

Advantages & Disadvantages

Kotlin helps to avoid some Java pitfalls, like null references and increase product quality and productivity. Kotlin's standard library is added on top of Java’s standard library, so app built with Kotlin will likely result in a larger file package size than one built purely in Java, and the build time for Kotlin will be a little slower using Gradle. The Kotlin Standard Library and runtime will increase the size of the .apk file. This equates to around 800KB, and in some cases that can make for a very large file. The Kotlin community is still fairly small, and developers do not have access to the same number of tutorials, blog posts, and user documentation as more established languages like Java.

Stack Overflow rating – Java vs Kotlin

In my opinion, Kotlin will be a game changer for Android development, and let's see how developers and companies will react. So dear reader, you can try it here right now!

Contact us to discuss your project.
We're ready to work with you.
Let's talk