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"
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
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"
Safe call Operator (?.)
It is used to safely access a property or method of a nullable object.
val length = name?.length
Elvis Operator (?:)
It provides a default value if the nullable variable is null.
val length = name?.length ?: 0 // Returns 0 if `name` is null
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
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
}
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
}
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
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}")
}
}
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