A Gentle Introduction to Kotlin For Java Programmers

Converting A Pixabay Image Viewer

Kotlin is a relatively new language based on the JVM. It was developed by JetBrains in 2011 and is currently supported by Google as an official development language for the Android platform. With that in mind, I decided it was time to learn the language. So as a means of learning to code in Kotlin, I decided to convert an existing Android application from my Github portfolio, written in Java, to Kotlin. The app I chose was a very simple image viewer. It performs a search of the Pixabay database and displays the results in a RecyclerView using a GridLayout. I ported two of the app’s activities, the initial search screen and the display screen. Here is a screen capture of the search screen with the search term “cats” – because the internet is nothing if not a giant database of cat pictures.



Here is what the user gets as a result:



Here is the link to the Java version of the app on Github. And here is a link to the Kotlin version.

So what was different about Kotlin?

The first thing a Java programmer notices about Kotlin is that it makes use of two new keywords when defining fields, var and val – defining fields which can change and those which can’t, respectively. You’ll also notice that the type comes after the name in Kotlin. So for instance, in Java, we’d write:

List imageURLs;

In Kotlin, the same variable would be written as:

var imageURLs : List

Of course, Kotlin also does away with the semicolon at the end of line – for those who felt oppressed by typing semicolons. And because the syntax is reversed, I often can’t help but hear the voice of Yoda when I am reading Kotlin saying, “Hmmm, define our variable names and then their types, we will.”

You’ll also notice that “methods” are now defined as “functions” using the “fun” keyword. And the word “override” is now a keyword instead of an annotation. So when overriding the OnCreate method in an Android Activity, we’d write this in Java…

@Override
protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
}

While in Kotlin, it would appear like this:

override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
}

Note that the question mark at the end of the word Bundle suggests that it can be nullable. By default, variables in Kotlin are not nullable. But they can be made nullable using the question mark syntax. This is actually a pretty big deal and contributes significantly to null-safety in Kotlin.

Kotlin also allows for implicit type declaration. So, for instance, the imageURLs field defined above could have been written as…

var imageURLs = listOf()

Kotlin will figure out that imageURLs is a List. And while on the topic of Lists, another feature of Kotlin is that Lists come in two flavors. By default, Lists are immutable. However, if you want a mutable list, you can use the following function to create one…

var imageURLs = mutableListOf()

And note another subtle feature of Kotlin. By the syntax above, you’d be forgiven for thinking that “List” is a concrete class. I actually made that assumption when I first saw the code. However, its not. List is an interface in Kotlin just like Java. Looking under the hood at the Kotlin source code, mutableListOf actually returns an ArrayList.

public fun mutableListOf(vararg elements: T): MutableList<T> =
  if (elements.size == 0) ArrayList()
  else ArrayList(ArrayAsCollection(elements, isVarargs = true))

Source: https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/kotlin/collections/Collections.kt#L96

The code is actually identical to Kotlin’s arrayListOf

public fun arrayListOf(vararg elements: T): ArrayList<T> =
  if (elements.size == 0) ArrayList()
  else ArrayList(ArrayAsCollection(elements, isVarargs = true))

There are a few other syntactic differences. Kotlin, for instance, replaces the keyword extends with a colon – much like C#.

Kotlin also has a nice feature called data classes. This is a special class that allows for the creation of data objects using a minimum of code. So, for instance, this class definition in Java…

public class MyData {
     private int someValue;
     MyData (int someValue) {
          this.someValue = someValue;
     }
     public int getSomeValue() {
          return someValue;
     }
}

…can be replaced with this in Kotlin…

data class MyData (val someValue : Int)

All of the boilerplate code is done for you.

What was the same with Kotlin?

First off, Kotlin is capable of using classes and interfaces just as you’ve seen in Java. So that will be a comfortable and familiar space for Java programmers. Kotlin also relies very heavily on the existing Android infrastructure. So, for instance, it uses the same Activity classes and follows the same Activity life cycle. You override the same onCreate method – except its called a function. In the case of the ImageViewer app, I overrode the same methods/functions in the same RecyclerView.Adapter class. So the port was remarkably straightforward. I also found that screen navigation is almost identical except for a few minor syntax changes. So, for instance, here is the code to start a new Activity in Java…

Intent multipleImagesDisplayActivityIntent = new Intent(this, MultipleImageDisplayActivity.class);
multipleImagesDisplayActivityIntent.putExtra(IMAGE_SEARCH_CRITERIA, searchCriteria);
startActivity(multipleImagesDisplayActivityIntent);

And here is the same Activity transition using Kotlin…

var multipleImagesDisplayActivityIntent : Intent = Intent(this, MultipleImageDisplayActivity::class.java)
multipleImagesDisplayActivityIntent.putExtra(IMAGE_SEARCH_CRITERIA, searchCriteria)
startActivity(multipleImagesDisplayActivityIntent)

Using the Retrofit library also proved to be a very straightforward port. Here is the code in Java for the Pixabay API…

@GET("api/")
Call getImages(
     @Query("key") String apiKey,
     @Query("q") String searchCriteria,
     @Query("page") int pageNumber);

And here is the same API in Kotlin…

@GET("api/")
fun getImages(
     @Query("key") apiKey: String,
     @Query("q") searchCriteria: String,
     @Query("page") pageNumber: Int)
     : Call

Conclusion

You can believe the hype that Kotlin is a straightforward port for Java programmers in Android. It relies very heavily on the existing Android framework and, but for a few syntactic differences, will feel very comfortable and familiar.