At Google’s I/O keynote, we learned that the Kotlin programming language would be officially supported on Android. Cue the sound of thousands of developers around the world high-fiving each other—many consider Java to be rather dated as a language (I am, admittedly, a Java lover).
Is the hype over Kotlin justified? There was just as much excitement over Swift, but many think the language isn’t ready and haven’t used it as a result.
Two years ago I swore I wouldn’t start seriously learning Kotlin until Google announced support for it. They’ve now done just that—and here I am learning it.
I wanted to learn this new language quickly, so I mustered all my super developer powers and drew on languages I was already familiar with (Java and Scala).
First Impressions
The first thing I noticed reading the Kotlin docs is that it compiles bytecode, JavaScript, and Native, and that it was developed by Jetbrains (of which I’m a big fan, like Android Studio). Let’s break that down.
If Kotlin compiles to bytecode, it means it’s using the JVM (Java Virtual Machine) to compile the bytecode to native machine code at runtime.
What about JavaScript? Basically, it’s transpiling the Kotlin code to JavaScript with the target ECMAScript 5.1. I’m no JavaScript expert, though—check out the official docs for more detailed info.
A smart move from Kotlin is the ability to compile native and have support for more platforms without the JVM—right now Kotlin Native can be targeted with Mac OS, Linux, Raspberry Pi, and iOS (by cross-compiling on a Mac) using the LLVM to generate the executables. Windows is not yet supported, but they’re working on it.
My dream scenario: To develop all the business logic of my Android and iOS application in Kotlin Native, then develop the UI in the specific platform language (Android = Java / Kotlin, iOS = Objective-C / Swift). Kotlin Native is still young, so I’ll have to wait before I can do that.
Another burning question:
Will Kotlin be 100% compatible with Java?
Look no further than the homepage for an answer:
Here’s my reaction:
But before we truly bust the moves out, it’s worth exploring things in a bit more detail.
If you read about Kotlin on the Internet, here’s what people are saying:
- Immutability
- Less code than Java
- Null safety
- Java interop
- Functional programming
Let’s poke around each one of these issues in detail and see if they hold any water.
Immutability
As with all languages that have functional programming concepts, immutability is one of the main talking points. How does it work in Kotlin?
The variables can be:
- Mutable: Represented by the keyword var
- Immutable: Represented by the keyword val
Is the keyword val really immutable?
Nope. When defining pure immutability, we always need to check if it satisfies the two types of immutability:
- Immutable references: Once a reference is assigned, it can’t be assigned to something else.
- Immutable values: The value of the reference cannot be mutated.
fun foo() { var mutable: Int = 1 val immutable: Int = 2 mutable = 2 // All OK immutable = 3 // Compile error val collection = arrayListOf(1, 2, 3) // Immutable reference to a collection collection.add(4) // Adding a value to the collection, so we are modifying the values of the immutable collection. }
So, does Kotlin have immutable collections?
Yes, it does.
You can choose between an immutable collection, map, set, etc., or not as the language has both implementations. Here’s an example:
fun bar() { val immutableList = listOf(1, 2, 3) // Immutable by reference and value val mutableList = mutableListOf(1, 2, 3) // Immutable by reference and not value }
Less Code Than Java
Kotlin has data classes that hold only data, so it’s a clean way to write all the POJO classes.
In Java:
public class Foo { private int id; private String name; public Foo(int id, String name) { this.id = id; this.name = name; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public int getId() { return id; } public String getName() { return name; } }
In Kotlin:
data class Foo(var id: Int, var name: String)
OK, I can hear you thinking: Why do you use var (mutable) instead of val (immutable)?
It’s because I made the Foo class in Java mutable.
Another way to write less code can be found in Kotlin Extensions. They let you add methods/functions to classes without modifying their source code—say goodbye Utils classes. The Kotlin team have used the extensions with the JDK classes such as files, IO, and threading.
Here’s an example from the standard library:
fun File.deleteRecursively(): Boolean
fun File.forEachLine( charset: Charset = Charsets.UTF_8, action: (line: String) -> Unit)
Null Safety
If you develop in Java, at some point you’ll have to deal with NPE (Null Pointer Exception), which pops up when you forget to check if a variable was null or if you just didn’t expect a null variable.
Kotlin has a smart fix: make all the types non-nullable by default. The compiler, therefore, won’t let you use a non-initialized or non-nullable variable. You can still use nullable types if you want though, by using the operator “?”.
Let me show you a couple of examples:
var foo = "Foo" foo = null // Compile error var bar: String? = "Bar" bar = null
You may be thinking that it’s not always possible to use a non-nullable type, as sometimes it’s out of your control—a network response issue, for example.
Don’t worry. Kotlin includes an “Elvis Operator” through which we can express the typical if else null check with this simple operator “?”:
val foo: String = bar ?: "Foo"
So goodbye if else expressions—you won’t be missed.
String foo = nullableResponse(); if (foo == null) { // do something } else { // do something }
The last crucial thing to mention is that you can use the operator “!!” in the same way as the operator “?”. The difference? It will throw up a NullPointerException if the variable is null, so please avoid using it!
Java Interop
This topic is of particular importance to me, because all my personal stack of libraries for work in Android or Backend are written in Java. I’m quite proud of them too, so I’d rather not change them right now.
As I said before, Kotlin is 100% compatible with Java.
Here are some examples using GSON and Retrofit:
@GET("playlistItems") fun playlistItems(@Query("part") part: String, @Query("maxResults") maxResult: Int, @Query("playlistId") playlistId: String, @Query("pageToken") pageToken: String?, @Query("key") key: String): Call
val response: Response = api.playlistItems(api.SNIPPET_PART, s.limit, s.playlistId, s.nextPageToken, googleApiKey).execute()
data class VideoResourceNetwork(@SerializedName("kind") val kind: String?, @SerializedName("videoId") val videoId: String?) : Model(identifier = videoId)
Here at Mobile Jazz we’ve developed Bugfender as a remote logging service for iOS and Android applications. The Android SDK was fully developed in Java. Kotlin can handle that—it can be used in your Kotlin Android Application because of the Java interop. Click here to see an example.
There’s lots more I’d like to share, but the Kotlin documentation is one of the best we’ve ever read. So head on over if you want to learn more.
Conclusions
Believe the hype — Kotlin is a mature language that gives Java developers a fresh start with a modern language. Java 8 was a really big step up from the previous Java versions, but as Android developers we can only use a small subset of Java 8’s features. Kotlin for us, then, is even better.
Have you tried Kotlin? Have we missed the mark with our overview? Get in touch and let us know your thoughts.
This post was edited by Steve Howe.