Kotlin Tutorial

Version 1.0 only became available in 2016, yet it’s already highly regarded: Kotlin, an alternative to Java. The object-based programming language comes from JetBrains, a Czech software development company. It scores points with its slim character and because it does not produce runtime errors so often – especially not the dreaded NullPointerExceptions. Kotlin is particularly popular for the development of Android apps. But also as a starting point for JavaScript applications, the young programming language is enormously popular.

Kotlin is closely based on Java: Although the two programming languages are not compatible, Kotlin is transformed into bytecode, which can be read by a Java Virtual Machine (JVM).

Instructions for Kotlin – with examples

In order to begin with Kotlin, you can download the compiler from the official website. It’s even simpler with an integrated development environment (IDE): IntelliJ IDEA (also from JetBrains), Eclipse (with corresponding plugin), NetBeans, and Android Studio work with Kotlin, for example.

Tip

The manufacturers of Kotlin have an online playground, where you can try all the examples.

Packages

At the beginning of a project, you import the packages you need to make your plan happen. You also define the package that you are currently working on. Packages contain classes and functions.

package test.bar
import foo.bar
import footoo.bar as footoo

To avoid problems with same names, you can rename packages in Kotlin with “as”. The naming of the packages does not have to follow the directory structure in which they can be found. For the sake of clarity, however, this procedure is recommended.

Note

Kotlin automatically loads the most important packages into each project.

Unlike Java, Kotlin also allows you to import individual functions from other packages. To do this, specify the correct path:

import foo.bar.myFunction

The function can then be used normally.

Tip

Code lines do not have to be completed in Kotlin by labelling – e.g. a semicolon.

Variables

Kotlin knows two different types of variables: Those that can only be read and are fixed and marked as “val”. Others, whose value can be changed during the course of the program, are marked as “var”.

val name = "Clara Oswald"
var age = 22

In contrast to the fixed name, the age can be adjusted, for example in a function.

Note

In this example, Kotlin has set the type of the value of the variable itself. It is also possible to specifically label these basic types.

Basic types

Kotlin works with certain types for variables and classes. Each type is an object, and Kotlin is slightly different from Java. While the older programming language first has to pack primitive types into a wrapper so that they behave like objects, this is not necessary with Kotlin. All types are already objects here.

Numbers

In Kotlin, you can insert numbers without a specific marker: the compiler understands that it should be numerical values. Commas are implemented by periods. If you want, you can also use hexadecimal numbers. For better readability, separators for thousands can be displayed using underscores. Kotlin knows different types of numbers, each of which can have a different maximum size:

  • Long: 64 bit
  • Int: 32 bit
  • Short: 16 bit
  • Byte: 8 bit
  • Double: 64 bit
  • Float: 32 bit

Double and float are floating-point numbers that behave differently to fixed-point numbers in complex calculations. Like all types, you can mark numbers precisely in your code.

val myNumber: Long = 40

It is possible to convert a number of one type to another.

val myInt = 600
val myLong= myInt.toLong()

The “toLong” command converts the “Int” value into a “Long” value. The command works in the same way for the other types of numbers.

String

A string is a word or a whole sentence, i.e. a string of characters. To use them in Kotlin, put the written text in double quotation marks. If you want to insert several lines of text, three double quotation marks are required at the beginning and end (raw string).

val myString = "This is a one-line string."
val myLongString = """This is a string,
that spans several lines."""

As in many other programming languages, the use of escape characters is possible in Kotlin: You use a backslash to mark a character that does not belong to the actual string, but is to be treated as a control character. Conversely, the backslash can also be used to insert characters into the string, which actually have a different meaning in Kotlin. The following escape characters are possible:

  • \t: Tab
  • \b: Backspace
  • \n: New line
  • \r: Carriage return
  • \': Single quotation mark
  • "\": Double quotation mark
  • \\: Backslash
  • \$: Dollar sign

The dollar sign is used in strings to insert placeholders. These can be set as variables in a previous step. The placeholder is then replaced in the output by an actual value.

val author = "Sandra"
val myString = "This text is from $author"

Characters

For individual characters, Kotlin also provides the special data type “character” in addition to strings. However, instead of placing them in double quotation marks, single quotation marks are used.

var model = 'A'

Boolean

The basic type “boolean” returns a truth value that can be either true or false.

Arrays

In Kotlin, an array is a collection of data. You form an array with “arrayOf()” or “Array()”. The first function is simple:

val myArray1 = arrayOf(0, 1, 2, 3, 4, 5)

This creates an array of numbers from 1 to 5, but these collections can also contain other types such as strings and booleans – even mixed. If you want to limit the array to one type, specify this in the function.

val myArray2 = arrayOf(10, 20, 30)
val myArray3 = booleanArrayOf(true, true, false)

The Kotlin constructor “Array()” is more complex: Here you also have to specify the length and a lambda function.

val myArray4 = Array(6, { i -> i })

The constructor creates an array with six digits and starts at zero: 0, 1, 2, 3, 4, 5.

Note

More about constructors and lambdas can be found below.

Each entry in an array is indexed and can be accessed via this index. Use square brackets to indicate the position of the entry in the list.

fun main() {
	val myArray5 = arrayOf("Jan", "Maria", "Samuel")
	println(myArray5[2])
}
Note

The function will output "Samuel" in this case, because the count starts with 0.

Operators

As you might know from many other programming languages, Kotlin also works with different operators that you can integrate into your source code. These include mathematical operators (+, -, *, /, %), comparison operators (<, >, <=, >=, ==, !=) and logical operators (&&, ||, !). So-called keywords are closely related to operators: terms that have a fixed meaning in Kotlin and cannot be reinterpreted.

Tip

A complete list of all keywords and operators can be found in the official Kotlin documentation.

Ranges

In Kotlin, a range describes a type that extends from a certain point to another. To create a range, use the operator “..” or the functions “rangeTo()” or “downTo()”. The variant with two points one behind the other can count upwards. With the two functions, you define which one direction.

val range1 = 1..5
val range2 = 1.rangeTo(5)
val range3 = 5.downTo(1)

In these simple versions, you create a range with single steps. To adjust the step size, you can additionally use the “step” function.

val range4 = 0..10 step(2)

To address individual data in the range, use the “in” operator. For example, you can create a query or a loop. To check whether a value is not part of the range, use the “!in” operator.

val range5 = 0..10
fun main() {
    for (n in range5) {
        println(n)
    }
    if (7 in range5) {
        println("yes")
    }
    if (12 !in range5) {
        println("no")
    }
}
Note

For more about functions, loops, and queries, see below.

Functions

Kotlin functions are always created with the “fun” command. You then define the name of the function, the arguments it contains, and finally what it does.

fun div(a: Int, b: Int): Int {
    return a/b
}
fun main() {
    println(div(100, 2))
}

First we define the function “div” (for division) with two Int parameters: a and b. The function should give us the result of the division of a by b, also in form of an Int variable. Finally, in the “main” function we access the previously defined function, transfer its concrete values, and display the result by “println” (print line) in the console. Kotlin executes the content of “main()” automatically. This function represents the entry point into a Kotlin program.

Fact

Kotlin does not accept commands other than functions. Only declarations are allowed.

In Kotlin, functions that contain only one line of code can be simplified. Instead of opening curly brackets, writing a new, inserted line and closing the braces again, an equal sign is used. The “return” command is also omitted.

fun div(a: Int, b: Int): Int = a/b
fun main() = println(div(100, 2))

To avoid errors due to missing parameters, you can specify default values when defining the function. If the corresponding parameters are left blank when the function is accessed, the default values are used.

fun div(a: Int = 10, b: Int = 5): Int = a/b
fun main() = println(div())

Lambda

A lambda function (or anonymous function) is a function that belongs neither to a class nor to an object. Lambdas are placed directly in other functions or variables. You can access them without using the keyword “fun”. In principle, lambda can be used like variables of type “val” and are generated in the same way.

fun main() {
    val myMessage = { println("Hello world!") }
    myMessage()
}

Lambda expressions in Kotlin must always be placed in curly braces. Lambdas can also process functional arguments. These are marked by an arrow that separates the parameters from the core of the expression.

fun main() {
    val div = {a: Int, b: Int -> a/b}
    println(div(6,2))
}

Classes

Just like in Java, classes in Kotlin are collections of data and functions. To define a class, simply insert the keyword “class”. Then you can fill the new class with information.

class Tardis {
    var year: Int
    var place: String
    constructor(year: Int, place: String) {
        this.year = year
        this.place = place
    }
}

In Kotlin, the constructor is a function that you need to create objects. The programming language knows primary and secondary constructors. Primary constructors are a practical shorthand, while secondary constructors are similar to the writing styles in many other object-orientated languages, including Java. You can see this second variant in the above example.

But there is also the possibility to omit the secondary constructor and use a primary constructor instead. You write this directly in the header line of the class and also specify the class parameters. This significantly reduces the number of lines of code.

class Tardis constructor(var year: Int, var place: String)

If you don't want to provide any additional information regarding the visibility of the class (public, private, protected), you can also omit the keyword altogether.

class Tardis (var year: Int, var place: String)

All three code examples produce the same result.

You can now use this class in your further source code and feed it with concrete values.

val tardis1 = Tardis(2133, "Dunlop Station")
val tardis2 = Tardis(1885, "Northampton")

As is common in most object-orientated languages, you can access the properties and methods of an object directly by placing a dot and the name of the property or method behind that of the object.

class Tardis (var year: Int, var place: String)
val tardis1 = Tardis(2133, "Dunlop Station")
val tardis2 = Tardis(1885, "Northampton")
fun main() {
    println(tardis1.year)
}

A special feature in Kotlin is the data class. This class type is intended to store data only. In principle, one line of code is sufficient for this.

data class User (var username: String, var name: String, var age: Int)

This class can be used directly.

data class User (var username: String, var name: String, var age: Int)
fun main() {
    val user1 = User ("River Song", "Melody Pond", 200)
    println("Username: " + user1.username)
    println("Name: " + user1.name)
    println("Age: " + user1.age)
}

Objects

Objects are instances in Kotlin that can only be defined once (singleton). They usually contain variables and functions. You create an object – similar to a class – in principle with only one line of code. In this case, however, the object is empty. You provide the object content in its body.

object myObject {
    fun sum(a: Int, b: Int): Int {
        return a+b
    }
}

Loops

In Kotlin, you can choose between three different loop types: “while”, “do..while”, and “if”. These behave like their equivalents in other programming languages. A “while” loop runs until a specified condition occurs.

fun main() {
    var n = 1
    while (n <= 10) {
        println(n++)
    }
}

The “do..while” loop behaves very similarly to the “while” variant. The difference is that the content of the loop is run at least once, since the check only takes place at the end.

fun main() {
    var n = 1
    do {
        n++
    }  
    while (n < 1)
    println(n)
}

The “for” loop runs as long as a condition remains true.

val myRange = 0..10
fun main() {
    for (n in myRange) {
        print("$n ")
    }
}

Conditions

Kotlin knows three different ways to implement conditional statements or branches: “if”, “if..else”, and “when”. The “if” query lets the computer do a task if the condition is true.

val whoCompanion = arrayOf("Bill Potts", "Clara Oswald", "Amy Pond", "Martha Jones", "Donna Noble", "Rose Tyler")
fun main() {
    if ("Rose Tyler" in whoCompanion) {
        print("yes")
    }
}

Use “else” to add an action to be executed if the condition does not apply.

val whoCompanions9 = arrayOf("Rose Tyler")
val whoCompanions10 = arrayOf("Martha Jones", "Donna Noble", "Rose Tyler")
val whoCompanions11 = arrayOf("Clara Oswald", "Amy Pond")
val whoCompanions12 = arrayOf("Bill Potts", "Clara Oswald")
fun main() {
    var whoCompanion = "Clara Oswald"
    if (whoCompanion in whoCompanions9) {
        print("yes")
    }
    else {
        print("no")
    }
}

Finally, the expression “when” is a special feature of Kotlin: different actions are carried out depending on different states. Thus the “when” expression is similar to what solves “switch” in other programming languages, but it works more precisely.

Different check cases are used when it comes to the body of “when”. These are always related to a defined variable.

var age = 17
fun main() {
    when {
        age > 18 -> println("You are too old!")
        age == 18 -> println("Already grown up!")
        age == 17 -> println("Welcome!")
        age <= 16 -> println("You are too young!")
    }
}

However, the argument can also be passed directly to “when” and does not have to be repeated every time in the body. In addition, a single condition can trigger multiple actions. Therefore, you create a new body with curly brackets. To exclude unexpected cases, “else” can help you.

fun multi(a: Int, b: Int, c: Int): Int {
    return a*b*c
}
fun main() {
    val d = "yes"
    when (d) {
        "no" -> println("No calculation")
        "yes" -> {
            println("Start calculation") 
            println(multi(5, 2, 100))
            println("Calculation finished")
        }
    else -> println("Incorrect input")    
    }
}

Nullability

A big annoyance factor when programming with Java is the NullPointerException error. This occurs if you link to an object whose value is “null”. Kotlin avoids this problem by not allowing variables to take the null value in the first place. If this should happen, the message "Null can not be a value of a non-null type String" appears when compiling – or a similar corresponding warning.

But there are moments when you want to use the “null” value consciously. For this Kotlin uses the safe call operator: “?”.

fun main() {
    var password: String? = null
    print(password)
}

With this, you explicitly let Kotlin know that “null” is acceptable. The program will then output “null”. However, if you want to address a certain property of the variable, you have to use the safe call operator again.

fun main() {
    var password: String? = null
    print(password?.length)
}

Also this code will produce “null” again, but no error – the program will still run. It is a bit more elegant if you specify an alternative value. For this you use the so-called Elvis operator: “?:” – so called because the smiley looks a bit like a quiff.

fun main() {
        val firstName = null
        val lastName = "Pond"
    val name: String = firstName?: + " " + lastName?:
    print(name)
}

In this example, information is displayed when a variable takes the value “null”.

Was this article helpful?
Page top