Kotlin | An Emerging language to power Android Application Development
Now that Google has embraced Kotlin-making it an official language on Android-cross-platform development has become a lot simpler. Let us understand what Kotlin is and its features.
Brief Overview of Kotlin
Kotlin is an OSS statically typed programming language that targets the JVM, Android, JavaScript and Native. It is developed by JetBrains. The project started in 2010 and was open source from very early on. The first official 1.0 release was in February 2016. It is a great fit for developing server-side applications, allowing one to write concise and expressive code while maintaining full compatibility with existing Java-based technology stacks and a smooth learning curve.
Kotlin is simple, clean and removes a lot of the code bloat from Java. Kotlin also adds some needed features that Java doesn’t yet support in Android.
Kotlin Features
- Null safety through nullable and non-nullable types, safe calls and safe casts
- Extension functions
- Higher-order functions/lambda expressions
- Data classes
- Immutability
- Coroutines
- Type aliases
Let’s Understand the Features in further detail
1. Null Safety:
Kotlin eliminates most sources of null references by making all types non-nullable by default meaning that the compiler will not let you use a non-initialized, non-nullable variable. If you need a variable to hold a null value, you have to declare the type as nullable, adding a question mark after the type.
In code, it looks like this:
var nonNullable: String = “My string” // needs to be initialized
var nullable: String?
Whenever you need to access a nullable variable, the compiler will enforce a null-check before accessing the variable. 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.
Below you can see the 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, prints null otherwise
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, and crashes with a NullPointerException otherwise.
2. Higher-order Functions and Lambdas:
One of Kotlin’s main features is higher-order functions a higher-order function takes functions as parameters or returns a function. One major use case for this is callback functions. We can create a function that makes a network call with two callbacks: one for success and another for error. In Kotlin, those would be two parameter functions, whereas in Java we would have to follow the pattern of having an interface and pass an instance that implements that interface— which requires much more code. Functions can be stored in variables for later use, passed around, or created inside another function. If a function is not declared but passed immediately as an expression, we call it a lambda, or an anonymous function. It is also called a “function literal.” Java 8 added support for lambdas, but if you are developing for Android, you are stuck with Java 7. This is one big reason why Kotlin is a great alternative to Java on Android.
3. Data Classes:
This feature is a great time saver. Given that most of our applications are data-driven, we often find ourselves creating classes with only properties and fields to hold data. In Java, this can be very tedious, requiring a get/set method for each field. With Kotlin, we can declare the class and all its properties in a single line. The compiler will generate all getters and setters, as well as the equality members, toString() and a copy() function.
For example, take this in Java:
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this. name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this. age;
}
// and the methods equals, hash-Code, copy, omitted for brevity
}
To run the same function in Kotlin, all we need is:
data class User(var name: String, var age: Int)
The compiler will generate everything we had to manually write in the above Java code.
4. Immutability:
One big concern developers need to have when developing multi-threaded applications is state management. If a variable is mutable, it can be changed by any thread that can access it. This means that if the data might be changed by multiple sources, you need to manually implement synchronization, which avoids data corruption but increases code complexity and execution time. If the data can never be changed, it can be accessed by multiple threads without error, since the data is immutable.
In Kotlin, We can declare variables with the keywords var and val. The former declares a variable that can be reassigned; the latter a variable that once assigned can never change. This gives the developer and the compiler confidence that the variable cannot be reassigned. Java has similar functionality with the final keyword, but the var/valkeywords carry more meaning. When used to declare properties, 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, say an ArrayList, the contents of the list can be changed, even though you cannot assign a new list to the same variable directly.
5. Coroutines:
In Kotlin 1.1, a new feature was added to the language: coroutines. Typically, when developers need to perform a long-running task such as a network operation or loading a file from a disk, the calling thread gets blocked waiting for the operation to complete. Coroutines enable us to execute those types of operations without blocking a thread. Instead, it is a lighter operation called suspension of a coroutine. We can write seemingly synchronous code that is in fact asynchronous and during compilation the code will be transformed to be asynchronous. This means that this technique does not rely on the underlying virtual machine or operating system.
6. Type Aliases:
In Kotlin 1.1, type aliases are a simple, yet very useful feature that will save you some keystrokes and make the code more readable. It is the ability to assign an alternative name, or alias, to any given type. This is most useful for long types with many generic parameters.
Example:
typealias MapOfLists = Map<String, List>
fun useMap(map: MapOfLists) {
// …
}
For a detailed comparison of Kotlin over Java, read my next blog Kotlin vs Java. What to choose?