January 23, 2017

Kotlin vs Java: An Introduction

Kotlin is a statically typed programming language for the Java Virtual Machine (JVM), Android, and web browsers crafted by the makers of the famous IDE IntelliJ[1]

The Willhaben Android App relies on traditional Java code and a growing amount of Kotlin code. Right now, we are in a transition period of migrating our legacy Java code to Kotlin. As Java and Kotlin both work on the JVM, they can be used in conjunction within the same codebase.

During my work with Kotlin, I stumbled upon some pretty interesting language details and features, some of which I want to explain briefly in the next few lines and in an upcoming blog post. I’ll also give you a comparison of how the same results can be achieved in the Java world. In this post, I will focus on two features.

JAVA VS KOTLIN: VERBOSITY


In contrast to Java, Kotlin generally needs many fewer lines of code for the same instructions.

Let's start off with a simple class definition as an example. The following plain Java Dog class provides some dog-describing attributes, like the dog’s age, name, etc., and getters and setters for these attributes.

public class Dog { 

   private int age; 
   private String name; 
   private int size; 
   private String breed; 

   public Dog(int age, String name, int size, String breed) { 
      this.age = age; 
      this.name = name; 
      this.size = size;
      this.breed = breed; 
   } 

   public int getAge() { 
      return age; 
   }

   public void setAge(int age) {  
      this.age = age; 
   } 

   public String getName() { 
      return name; 
   } 

   public void setName(String name) {        
      this.name = name; 
   } 

   public int getSize() { 
      return size; 
   } 

   public void setSize(int size) { 
      this.size = size; 
   } 

   public String getBreed() { 
      return breed; 
   } 

   public void setBreed(String breed) { 
      this.breed = breed; 
   } 

}󠁊󠀷󠁁󠁜󠀤

The same class, rewritten in Kotlin [3], can be defined with only a single line of code. It is noteworthy to mention that there is no need to provide getter- or setter-methods manually, unless a getter/setter executes additional code, which would require the method to be explicitly overridden.

data class Dog(var age: Int,  var name: String?, var size: Int, var breed: String?)󠁊󠀷󠁁󠁜󠀤

KOTLIN'S NICE OPERATORS


Elvis operator


Kotlin provides some helpful operators that might be known to you from other languages, but which are not available in Java at this point.

One of them is the so-called “Elvis operator,” which is similar to Java's ternary operator, but again, leads to less verbose statements.

The following Java code declares a variable text. Then, there is some processing going on with this variable (not shown), and we need to make sure that text is neither null nor assigned a default fallback String. The first version of this check uses a simple if-expression to achieve this behavior, which is quite a lot to type for such a simple task. The second version is based on the use of a ternary operator, which further reduces the line count, but there is still the need to check for the null value.

String text;

// ... do something with text …

// First version: using a plain if expression
if (text == null) {
    text = "Nothing found";
}

// Second version: using the ternary operator
text = (text == null) ? "Nothing found" : text;󠁊󠀷󠁁

Here is the same scenario in Kotlin using the Elvis operator (?:) [2]. The part before ?: defines what to assign if the variable text already has a value other than null, while the part after the operator specifies a default value.

var text: String? = null

// ... do something with text …

text = text ?: "Nothing found."󠁊󠀷󠁁󠁜󠀤

Safe calls


Let's imagine our dog class from above. Now, it also provides an attribute father and its corresponding getter/setter.

Have you ever seen horrible if-constructs like the following, to make sure that each of the chained calls returns a non-null value?

Dog beethoven = new Dog(8, "Beethoven", 35, "Pug");
Dog lessie = new Dog(5, "Lessie", 25, "Chihuahua-Pug");
lessie.setFather(beethoven);

// some code ...

if (lessie!= null && lessie.father() != null) {
    System.out.println("The father of Princess is: " + lessie.father().name);
}󠁊󠀷󠁁

Fear no more, with Kotlins “Safe Call” (?) operator [2]the code above can be rewritten as follows:

val beethoven:Dog? = Dog(8, "Beethoven", 35, "Pug")
val lessie:Dog? = Dog(5, "Lessie", 25, "Chihuahua-Pug")
lessie?.father = beethoven

// some code ...

System.out.println("The father of Lessie is: " + lessie?.father?.name)󠁊

As you can see, the chained lessie?.father?.name call which makes use of the ?-operator now allows us to omit the repeated != null checks for “lessie ” and “father.” If either “lessie ” or “father” returns null, the evaluation of the next chain call is aborted, and null is returned. Please note, that name could still return null; however, for the sake of simplicity, there is no check in the example for such a case.

Summary


All right, now you have had a glimpse into Kotlin, but there is still much more to explore. This blog describes the code verbosity and Kotlin operators compared to Java.

In summary, Kotlin has really good features that are not available in Java at this time. For Java developers, Kotlin is both easy to understand and nice to work with.

Some other nice features are Smart Casts, Lambda expressions, and Inline functions. I want to discuss those in my next blog.

3 comments:

  1. Omg! Thanks so much for the article. I`ll use your pieces of advice for my custom thesis website. Thank you!

    ReplyDelete
  2. I really appreciated understanding it, you may be an awesome author.I will make sure to bookmark your blog and will in the long run return later. professional non-plagiarized writing service

    ReplyDelete