Kotlin is a modern Java alternative programming language. Kotlin originally was developed by JetBrains, the company behind IntelliJ IDEA, in 2010, and has been open source since 2012.
Kotlin runs on Java Virtual Machine (JVM) therefore its 100% compatible with Java. In 2017 Kotlin was named an official development language for the Android platform.
Why Kotlin?
Familiar syntax
Its syntax is familiar to any programmer who has been brought up on the OOP paradigm, and from the very beginning can be more or less understandable. Of course, there are some differences from Java, such as a redesigned constructor or variable declarations val and var. Just take a look at this code that reflects most of the Kotlin basic syntax:
class KotlinClass { val b: String = "b" // val means unmodifiable var i: Int = 0 // var means modifiable fun foo() { val str = "Hello" print("$str Kotlin!") } fun sum(x: Int, y: Int): Int { return x + y } fun maxOf(a: Float, b: Float) = if (a > b) a else b }
String interpolation
It’s something like a smarter and more readable version of String.format()
from Java that built into the language:
val x = 5 val y = 6 print("sum of $x and $y is ${x + y}") // sum of 5 and 6 is 11
Type derivation
Kotlin will infer your types if you think this will improve the readability:
val a = "xyz" // type inferred to String val b = 7 // type inferred to Int val c: Double = 0.37 // type declared explicitly val d: List<String> = ArrayList() // type declared explicitly
Smart Casts
The Kotlin compiler keeps track of your logic and, as far as possible, automatically performs casts, that is, you no longer need to test instanceof
after explicit casts:
if (obj is String) { print(obj.toUpperCase()) // obj is now known as a String }
Intuitive Equals
No equals()
required, because the ==
operator now checks the structural equality:
val bob1 = Person("Bob") val bob2 = Person("Bob") bob1 == bob2 // true (structural equality) bob1 === bob2 // false (referential equality)
Default Arguments
It is no longer necessary to define several identical methods with different arguments:
fun build(title: String, width: Int = 500, height: Int = 300) { Window(title, width, height) }
Named arguments
In combination with the default arguments, named arguments eliminate the need to use Builders:
build("Yuri", 500, 300) // same build(title = "Yuri", width = 500, height = 300) // same build(width = 500, height = 300, title = "Yuri") // same
When expression
when (x) { 1 -> print("x is 1") 2 -> print("x is 2") 3, 4 -> print("x is 3 or 4") in 5..10 -> print("x is 5, 6, 7, 8, 9, or 10") else -> print("x is out of range") }
when expression also can be used as a statement with or without arguments:
val res: Boolean = when { obj == null -> false obj is String -> true else -> throw IllegalStateException() }
Ranges
for (i in 1..1000) { ... } for (i in 0 until 1000) { ... } for (i in 2..10 step 2) { ... } for (i in 10 downTo 1) { ... } if (x in 1..10) { ... }
Extension Functions
fun String.format(): String { return this.replace(' ', '_') } val formatted = str.format()
Kotlin’s standard library enhances original Java types:
str.removeSuffix(".py") str.capitalize() str.substringAfterLast("/") str.replaceAfter(":", "error")
Null Safety(at last!)
var a: String = "hi" a = null // compile error var b: String? = "bye" b = null // no problem val x = b.length // compile error: b might be null if (b == null) return val x = b.length // no problem val x = b?.length // type of x is nullable Int val name = ship?.captain?.name ?: "unknown" val x = b?.length ?: throw NullPointerException() // same as below val x = b!!.length // same as above
Better Lambda
val sum = { x: Int, y: Int -> x + y } // type: (Int, Int) -> Int val result = sum(3,8) // result == 11
students .filter { it.age >= 27 } .sortedBy { it.name } .map { it.cell_number } .forEach { print(it) }
Integration with IntelliJ
IntelliJ allows automatic conversion from Java code to Kotlin: