[Kotlin](https://kotlinlang.org/)is a programming language widely used by Android developers everywhere. This topic serves as a Kotlin crash-course to get you up and running quickly.

## Variable declaration

Kotlin uses two different keywords to declare variables:`val`and`var`.

- Use`val`for a variable whose value never changes. You can't reassign a value to a variable that was declared using`val`.
- Use`var`for a variable whose value can change.

In the example below,`count`is a variable of type`Int`that is assigned an initial value of`10`:  

    var count: Int = 10

`Int`is a type that represents an integer, one of the many numerical types that can be represented in Kotlin. Similar to other languages, you can also use`Byte`,`Short`,`Long`,`Float`, and`Double`depending on your numerical data.

The`var`keyword means that you can reassign values to`count`as needed. For example, you can change the value of`count`from`10`to`15`:  

    var count: Int = 10
    count = 15

Some values are not meant to be changed, though. Consider a`String`called`languageName`. If you want to ensure that`languageName`always holds a value of "Kotlin", then you can declare`languageName`using the`val`keyword:  

    val languageName: String = "Kotlin"

These keywords allow you to be explicit about what can be changed. Use them to your advantage as needed. If a variable reference must be reassignable, then declare it as a`var`. Otherwise, use`val`.

### Type inference

Continuing the previous example, when you assign an initial value to`languageName`, the Kotlin compiler can infer the type based off of the type of the assigned value.

Since the value of`"Kotlin"`is of type`String`, the compiler infers that`languageName`is also a`String`. Note that Kotlin is a*statically-typed*language. This means that the type is resolved at compile time and never changes.

In the following example,`languageName`is inferred as a`String`, so you can't call any functions that aren't part of the`String`class:  

    val languageName = "Kotlin"
    val upperCaseName = languageName.toUpperCase()

    // Fails to compile
    languageName.inc()

`toUpperCase()`is a function that can only be called on variables of type`String`. Because the Kotlin compiler has inferred`languageName`as a`String`, you can safely call`toUpperCase()`.`inc()`, however, is an`Int`operator function, so it can't be called on a`String`. Kotlin's approach to type inference gives you both conciseness and type-safety.

### Null safety

In some languages, a reference type variable can be declared without providing an initial explicit value. In these cases, the variables usually contain a null value. Kotlin variables can't hold null values by default. This means that the following snippet is invalid:  

    // Fails to compile
    val languageName: String = null

For a variable to hold a null value, it must be of a*nullable* type. You can specify a variable as being nullable by suffixing its type with`?`, as shown in the following example:  

    val languageName: String? = null

With a`String?`type, you can assign either a`String`value or`null`to`languageName`.

You must handle nullable variables carefully or risk a dreaded`NullPointerException`. In Java, for example, if you attempt to invoke a method on a null value, your program crashes.

Kotlin provides a number of mechanisms for safely working with nullable variables. For more information, see[Common Kotlin patterns in Android: Nullability](https://developer.android.com/kotlin/common-patterns#nullability).

## Conditionals

Kotlin features several mechanisms for implementing conditional logic. The most common of these is an*if-else statement* . If an expression wrapped in parentheses next to an`if`keyword evaluates to`true`, then code within that branch (i.e. the immediately-following code that is wrapped in curly braces) is executed. Otherwise, the code within the`else`branch is executed.  

    if (count == 42) {
        println("I have the answer.")
    } else {
        println("The answer eludes me.")
    }

You can represent multiple conditions using`else if`. This lets you represent more granular, complex logic within a single conditional statement, as shown in the following example:  

    if (count == 42) {
        println("I have the answer.")
    } else if (count > 35) {
        println("The answer is close.")
    } else {
        println("The answer eludes me.")
    }

Conditional statements are useful for representing stateful logic, but you may find that you repeat yourself when writing them. In the example above, you simply print a`String`in each branch. To avoid this repetition, Kotlin offers*conditional expressions*. The last example can be rewritten as follows:  

    val answerString: String = if (count == 42) {
        "I have the answer."
    } else if (count > 35) {
        "The answer is close."
    } else {
        "The answer eludes me."
    }

    println(answerString)

Implicitly, each conditional branch returns the result of the expression on its final line, so you don't need to use a`return`keyword. Because the result of all three branches is of type`String`, the result of the if-else expression is also of type`String`. In this example,`answerString`is assigned an initial value from the result of the if-else expression. Type inference can be used to omit the explicit type declaration for`answerString`, but it's often a good idea to include it for clarity.
| **Note:** Kotlin does not include a traditional[ternary operator](https://en.wikipedia.org/wiki/%3F:), instead favoring the use of conditional expressions.

As the complexity of your conditional statement grows, you might consider replacing your if-else expression with a*when*expression, as shown in the following example:  

    val answerString = when {
        count == 42 -> "I have the answer."
        count > 35 -> "The answer is close."
        else -> "The answer eludes me."
    }

    println(answerString)

Each branch in a`when`expression is represented by a condition, an arrow (`->`), and a result. If the condition on the left-hand side of the arrow evaluates to true, then the result of the expression on the right-hand side is returned. Note that execution does not fall through from one branch to the next. The code in the`when`expression example is functionally-equivalent to that in the previous example but is arguably easier to read.

Kotlin's conditionals highlight one of its more powerful features,*smart casting*. Rather than using the safe-call operator or the not-null assertion operator to work with nullable values, you can instead check if a variable contains a reference to a null value using a conditional statement, as shown in the following example:  

    val languageName: String? = null
    if (languageName != null) {
        // No need to write languageName?.toUpperCase()
        println(languageName.toUpperCase())
    }

Within the conditional branch,`languageName`may be treated as non-nullable. Kotlin is smart enough to recognize that the condition for executing the branch is that`languageName`does not hold a null value, so you do not have to treat`languageName`as nullable within that branch. This smart casting works for null checks,[type checks](https://kotlinlang.org/docs/reference/typecasts.html#is-and-is-operators), or any condition that satisfies a[contract](https://kotlinlang.org/docs/reference/whatsnew13.html#contracts).

## Functions

You can group one or more expressions into a*function*. Rather than repeating the same series of expressions each time that you need a result, you can wrap the expressions in a function and call that function instead.

To declare a function, use the`fun`keyword followed by the function name. Next, define the types of inputs that your function takes, if any, and declare the type of output that it returns. A function's body is where you define expressions that are called when your function is invoked.

Building on previous examples, here's a complete Kotlin function:  

    fun generateAnswerString(): String {
        val answerString = if (count == 42) {
            "I have the answer."
        } else {
            "The answer eludes me"
        }

        return answerString
    }

The function in the example above has the name`generateAnswerString`. It doesn't take any input. It outputs a result of type`String`. To call a function, use its name, followed by the invocation operator (`()`). In the example below, the`answerString`variable is initialized with the result from`generateAnswerString()`.  

    val answerString = generateAnswerString()

Functions can take arguments as input, as shown in the following example:  

    fun generateAnswerString(countThreshold: Int): String {
        val answerString = if (count > countThreshold) {
            "I have the answer."
        } else {
            "The answer eludes me."
        }

        return answerString
    }

When declaring a function, you can specify any number of arguments and their types. In the example above,`generateAnswerString()`takes one argument named`countThreshold`of type`Int`. Within the function, you can refer to the argument by using its name.

When calling this function, you must include an argument within the function call's parentheses:  

    val answerString = generateAnswerString(42)

### Simplifying function declarations

`generateAnswerString()`is a fairly simple function. The function declares a variable and then immediately returns. When the result of a single expression is returned from a function, you can skip declaring a local variable by directly returning the result of the if-else expression contained in the function, as shown in the following example:  

    fun generateAnswerString(countThreshold: Int): String {
        return if (count > countThreshold) {
            "I have the answer."
        } else {
            "The answer eludes me."
        }
    }

You can also replace the return keyword with the assignment operator:  

    fun generateAnswerString(countThreshold: Int): String = if (count > countThreshold) {
            "I have the answer"
        } else {
            "The answer eludes me"
        }

### Anonymous functions

Not every function needs a name. Some functions are more directly identified by their inputs and outputs. These functions are called*anonymous functions*. You can keep a reference to an anonymous function, using this reference to call the anonymous function later. You can also pass the reference around your application, as with other reference types.  

    val stringLengthFunc: (String) -> Int = { input ->
        input.length
    }

Like named functions, anonymous functions can contain any number of expressions. The returned value of the function is the result of the final expression.

In the example above,`stringLengthFunc`contains a reference to an anonymous function that takes a`String`as input and returns the length of the input`String`as output of type`Int`. For that reason, the function's type is denoted as`(String) -> Int`. This code does not invoke the function, however. To retrieve the result of the function, you must invoke it with like you would a named function. You must supply a`String`when calling`stringLengthFunc`, as shown in the following example:  

    val stringLengthFunc: (String) -> Int = { input ->
        input.length
    }

    val stringLength: Int = stringLengthFunc("Android")

### Higher-order functions

A function can take another function as an argument. Functions that use other functions as arguments are called*higher-order functions*. This pattern is useful for communicating between components in the same way that you might use a callback interface in Java.

Here's an example of a higher-order function:  

    fun stringMapper(str: String, mapper: (String) -> Int): Int {
        // Invoke function
        return mapper(str)
    }

The`stringMapper()`function takes a`String`along with a function that derives an`Int`value from a`String`that you pass into it.

You can call`stringMapper()`by passing a`String`and a function that satisfies the other input parameter, namely a function that takes a`String`as input and outputs an`Int`, as shown in the following example:  

    stringMapper("Android", { input ->
        input.length
    })

If the anonymous function is the*last*parameter defined on a function, you can pass it outside of the parentheses used to invoke the function, as shown in the following example:  

    stringMapper("Android") { input ->
        input.length
    }

Anonymous functions can be found throughout the Kotlin standard library. For more information, see[Higher-Order Functions and Lambdas](https://kotlinlang.org/docs/reference/lambdas.html).

## Classes

All of the types mentioned so far are built into the Kotlin programming language. If you would like to add your own custom type, you can define a class using the`class`keyword, as shown in the following example:  

    class Car

### Properties

Classes represent state using properties. A[property](https://kotlinlang.org/docs/reference/properties.html)is a class-level variable that can include a getter, a setter, and a backing field. Since a car needs wheels to drive, you can add a list of`Wheel`objects as a property of`Car`, as shown in the following example:  

    class Car {
        val wheels = listOf<Wheel>()
    }

Note that`wheels`is a`public val`, meaning that`wheels`can be accessed from outside of the`Car`class, and it can't be reassigned. If you want to obtain an instance of`Car`, you must first call its constructor. From there, you can access any of its accessible properties.  

    val car = Car() // construct a Car
    val wheels = car.wheels // retrieve the wheels value from the Car

If you want to customize your wheels, you can define a custom constructor that specifies how your class properties are initialized:  

    class Car(val wheels: List<Wheel>)

In the example above, the class constructor takes a`List<Wheel>`as a constructor argument and uses that argument to initialize its`wheels`property.

### Class functions and encapsulation

Classes use functions to model behavior. Functions can modify state, helping you to expose only the data that you wish to expose. This access control is part of a larger object-oriented concept known as*encapsulation*.

In the following example, the`doorLock`property is kept private from anything outside of the`Car`class. To unlock the car, you must call the`unlockDoor()`function passing in a valid key, as shown in the following example:  

    class Car(val wheels: List<Wheel>) {

        private val doorLock: DoorLock = ...

        fun unlockDoor(key: Key): Boolean {
            // Return true if key is valid for door lock, false otherwise
        }
    }

If you would like to customize how a property is referenced, you can provide a custom getter and setter. For example, if you would like to expose a property's getter while restricting access to its setter, you can designate that setter as`private`:  

    class Car(val wheels: List<Wheel>) {

        private val doorLock: DoorLock = ...

        var gallonsOfFuelInTank: Int = 15
            private set

        fun unlockDoor(key: Key): Boolean {
            // Return true if key is valid for door lock, false otherwise
        }
    }

With a combination of properties and functions, you can create classes that model all types of objects.

## Interoperability

One of Kotlin's most important features is its fluid interoperability with Java. Because Kotlin code compiles down to JVM bytecode, your Kotlin code can call directly into Java code and vice-versa. This means that you can leverage existing Java libraries directly from Kotlin. Furthermore, the majority of Android APIs are written in Java, and you can call them directly from Kotlin.

## Next steps

Kotlin is a flexible, pragmatic language with growing support and momentum. We encourage you to give it a try if you haven't yet. For next steps, take a look at the[official Kotlin documentation](https://kotlinlang.org/)along with the guide on how to apply[common Kotlin patterns](https://developer.android.com/kotlin/common-patterns)in your Android apps.