Kotlin is a modern programming language which targets java platform and run on JVM. Although it’s not a very new language but it has become quite popular after Google started to support Kotlin as its official language. Kotlin v1.0 developed by JetBrains was released way back in Feb, 2016. Kotlin is concise, more expressive than Java, safe, functional, pragmatic and interoperable with Java.
Kotlin Primary Features
Kotlin has most of the key features a modern programming language should have. Kotlin is based on JVM and aims to provide a safer alternative to Java. Java is an immensely popular language and used in a vast variety of platforms (eg. From embedded systems to Data centers). Kotlin can do most of the work which is done by Java like building server applications, android applications and running microservices. It can also be compiled to Javascript which means you can run Kotlin in Browser. But here are some of the key traits which are not present in Java
1. Expressiveness
Kotlin can help you in reducing the amount of boilerplate code that you write, results in saving your time to write business logic code.For example, if you are building a mobile application, you will have to write (or atleast generate) a POJO class like below -
public class Actor {
private long id;
private String name;
private int age;
private String url;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "Actor{" +
"id=" + id +
", name=" + name +
", age=" + age +
", url=" + url +
"}";
}
}
Imagine if you have 20s or 50s of such POJO. It would be difficult to write all those classes and overriding toString()
, equals()
and hashCode()
etc. In Kotlin, you just need to use data class:
data class Actor(
var id: Long,
var name: String,
var age: Int,
var url: String
)
And Kotlin will write all the boilerplate code (setters, getters and even overrides the equals() and hashCode()) which makes code less verbose and more expressive.
2. Statically Typed
Kotlin is a statically typed language same as Java. Statically typed means that the type of every expression is known at compile time and thus compiler can validate the methods and fields. But unlike java, Kotlin doesn’t require you to specify the type of every variable explicitly. Most of the time, it can automatically be determined by the context. This ability of compiler (determining type by context) is known as Type Interference.
val x = 10;
Here, a variable is initialized with an integer value, so Kotlin Compiler automatically determines the type of variable x which is Int.
3. Null Safety
While writing java code, you may find a situation when your app throws a NullPointerException (The Billion Dollar Mistake) and then you realized that you forgot to add a null check. In Java, you constantly need to check if your instance reference is null or not before using it, thus making the code defensive. Kotlin’s type system is aimed to eliminate NPE’s from code, thus making Kotlin a null safe language like many other modern language. You have to explicitly specify if something can be null or not by using ? operator. Only possible situations when a NPE can be thrown:
- Calling
throw NullPointerException()
explicitly. - Usage of
!! operator
(will be described in some other post). - Data inconsistency with initialization.
- Java Interoperation (accessing a member of null reference of a platform type, Generic type with incorrect nullability, etc).
4. Object Oriented and Functional
While Kotlin is a Object Oriented programming language, it’s functions and properties are first class. First class functions means you can work with them as values, store in variables, pass them as arguments or even return them from other Higher Order Functions (will be explained in other post). In short, you can use them as you use non-function values which also provides more abstraction and less duplication of code. Using functional programming (Wikipedia has a very good article written about it) paradigm, objects become immutable, which guarantees that their state can’t be changed after creation. Functional style programming is more concise, elegant and succinct compared to imperative programming. Kotlin has many features to support functional style programming, some of them are listed below:
- Functional Types - allows functions to receive other function as parameters or return other functions.
fun <T, R> Collection<T>.fold(
initial: R,
combine: (acc: R, nextElement: T) -> R
): R {
var accumulator: R = initial
for (element: T in this) {
accumulator = combine(accumulator, element)
}
return accumulator
}
- Lambda Expressions - A lambda expression is a function literal (way of defining functions) that are not declared, but passed as an expression which prevents you from having to write the specification in an abstract class or interface and then implementation in a class.
val sum = { x: Int, y: Int -> x + y }
- Data Classes - Already explained earlier.
5. Use-site Variance
Generic types in java are invariant. There are wildcards in java but Kotlin doesn’t have any. In java, Collection<String>
is a subtype of Collection<? extends Object>
but not a subtype of Collection<Object>
which is obvious to ensure runtime-safety.
interface Collection<E> ... {
void addAll(Collection<? extends E> items);
}
The wildcard type argument ? extends E
means we can safely read E's from the items but can not write to it because we don't know what objects comply to that unknown subtype of E. This extends-bound (upper bound) is of covariant type. Similarly, there is contravariant type super-bound (lower bound) which suggest that you can only write E to the collections of `? super E` but can not read E's from it.
Kotlin doesn’t have any such wildcards but have variance annotations. Kotlin Provides two type of variance annotation, out (makes a type parameter covariant) and in (makes a type variant contravariant). Consider the following example:
interface Event<out T> {
fun nextT(): T
}
fun demo(strs: Event<String>) {
val objects: Event<Any> = strs // This is OK, since T is an out-parameter
}
out variance is kind of Producer (? extends
) and complementary in variance is kind of Consumer (? super
) (Similar to PECS). The above kind of variance declaration is known as Declaration-site Variance which is quite similar to Java wildcards but less verbose and complex.
PECS: Producer Extends, Consumer Super.
In addition to Declaration-site Variance, Kotlin supports Use-site Variance (Type projections). Sometimes, there are situations where a type parameter can not be either co- or contravariant. Have a look to the following class:
class Event<T> {
fun pull(): T { ... }
fun push(event: T) { ... }
}
Here, Event
can not be restricted to only either produce or consume T’s. The following function maps the event and convert that into some other event.
fun map(from: Event<Any>, to: Event<Any>) {
// Map the from event into to
}
val userId: Event<String>
val user: Event<User>
map(userId, user) // Error: because it expects (Event<Any>, Event<Any>)
Event<T>
is invariant in T so Event<String>
or Event<User>
is not a subtype of Event<Any>
. So to ensure that map function only read from from
and doesn’t do any bad, for example writing to from
, we need to prevent it. It can be done by using out variance on site like below.
fun map(from: Event<out Any>, to: Event<Any>) {
// Map the from event into to
}
This approach is known as type projection. In a similar way, you can use in variance also to only write to that particular parameter.
Use of Kotlin
Kotlin can be at various places where Java is used but two main usage of Kotlin to look upon are Kotlin on Server side and Kotlin on Android.
Server side programming includes a variety of applications like web apps, backend for mobile apps and even microservices to communicate. Kotlin is completely interoperable with java so no need to worry about working with existing codebase. Kotlin lets you use functional style programming to write code with more confidence and concise syntax and full abstraction. In addition to that, Kotlin also has coroutines to write code that works asynchronously which makes writing microservices more easy.
Kotlin language feature with a support plugin, turns android development into a much pleasurable experience and let you write less number of lines for code. Adding listeners to view events, binding layouts and asynchronous programming, all these can be done by Kotlin in very less code or even no sometimes. A library named Anko built by Kotlin team, can be used to generate layout without using xmls. All these combined together provides you a nicer experience for building android apps.
Final Words
Kotlin is a powerful modern language which seamlessly work with a very old and popular language Java. The above mentioned features are only the key features of it, there are many more to describe but this post can not accommodate all of them. If you are a new android developer, you must start learning Kotlin as well because it’s supported by Google so you can expect lots of new tools and apis built around Kotlin. If you are experienced with Java and Android Development, you should try Kotlin to increase your productivity and write much more meaningful code.
Thanks for reading so far. I hope you have enjoyed this article. If you have any suggestions or query, kindly do comment below.