Introduction to Kotlin

Madhav Ganesan - Feb 4 - - Dev Community

Kotlin is a modern, statically-typed programming language that runs on the Java Virtual Machine (JVM) and is designed to be fully interoperable with Java. It was developed by JetBrains, the same company behind IntelliJ IDEA, and was officially released in 2011. Kotlin became popular for its concise, expressive syntax and modern features, making it an excellent choice for Android, backend, and other types of software development.

Features

Concise Syntax

It reduces boilerplate code significantly compared to Java, making code cleaner and easier to read.
Ex.

val name: String = "Kotlin"
Enter fullscreen mode Exit fullscreen mode

Interoperability

It can call Java code, and Java can call Kotlin code. This makes it easy to use Kotlin in existing Java projects without rewriting everything.

Null Safety

It is a feature that helps prevent errors caused by accessing or using null references. In languages that support null safety, such as Kotlin, the language ensures at compile time that nullable variables are handled properly, reducing the likelihood of runtime exceptions like the infamous NullPointerException (NPE) in Java.

It introduces a robust null-safety system to reduce NullPointerException (NPE) errors.

Nullable Types (?)

var name: String? = null // Nullable variable
Enter fullscreen mode Exit fullscreen mode

This means the name variable can either hold a String value or null.

Non-Nullable Types
By default, variables in Kotlin are non-nullable

var name: String = "Kotlin"
Enter fullscreen mode Exit fullscreen mode

Safe call Operator (?.)

It is used to safely access a property or method of a nullable object.

val length = name?.length
Enter fullscreen mode Exit fullscreen mode

Elvis Operator (?:)

It provides a default value if the nullable variable is null.

val length = name?.length ?: 0 // Returns 0 if `name` is null
Enter fullscreen mode Exit fullscreen mode

Non-Null Assertion (!!)

It forcefully asserts that a variable is not null. If the variable is null, a NullPointerException will be thrown.

val length = name!!.length // Throws an exception if `name` is null
Enter fullscreen mode Exit fullscreen mode

Smart Casts

It simplifies working with variables by allowing the compiler to automatically cast a variable to a specific type when it's guaranteed to be safe.
It eliminates the need for explicit typecasting when the compiler can guarantee that the type of a variable is valid in the current context.

fun printStringLength(value: Any?) {
    if (value is String) { 
        // Smart cast: 'value' is automatically cast to 'String' within this block
        println("String length: ${value.length}")
    } else {
        println("Not a string or null")
    }
}

fun main() {
    printStringLength("Kotlin") // Output: String length: 6
    printStringLength(123)      // Output: Not a string or null
    printStringLength(null)     // Output: Not a string or null
}
Enter fullscreen mode Exit fullscreen mode

Coroutines

It provides a way to write asynchronous, non-blocking code that is easy to read and maintain. They are like lightweight threads that allow you to manage multiple tasks concurrently without the overhead of traditional threads.

import kotlinx.coroutines.*

fun main() = runBlocking {
    println("Start") // Main thread
    launch {
        delay(1000L) // Non-blocking delay
        println("Coroutine!") // Will execute after 1 second
    }
    println("End") // Main thread continues
}
Enter fullscreen mode Exit fullscreen mode
fun main() = runBlocking {
    val deferred1 = async {
        delay(1000L)
        "Result 1"
    }
    val deferred2 = async {
        delay(1500L)
        "Result 2"
    }
    println("Waiting for results...")
    println("Results: ${deferred1.await()} and ${deferred2.await()}")
}

//Output
//Waiting for results...
//Results: Result 1 and Result 2
Enter fullscreen mode Exit fullscreen mode

Dispatchers in Coroutines

  • Dispatchers.Default: For CPU-intensive work.
  • Dispatchers.IO: For network or disk I/O operations.
  • Dispatchers.Main: For UI updates.
fun main() = runBlocking {
    launch(Dispatchers.IO) {
        println("Running on IO thread: ${Thread.currentThread().name}")
    }
    launch(Dispatchers.Default) {
        println("Running on Default thread: ${Thread.currentThread().name}")
    }
    launch(Dispatchers.Main.immediate) {
        println("Running on Main thread: ${Thread.currentThread().name}")
    }
}
Enter fullscreen mode Exit fullscreen mode

Stay Connected!
If you enjoyed this post, don’t forget to follow me on social media for more updates and insights:

Twitter: madhavganesan
Instagram: madhavganesan
LinkedIn: madhavganesan

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .