Kotlin Beginner
Statically typed cross-platform language — concise syntax, 100% Java interoperability, and compiler-level Null Safety.
Table of Contents
Variables & Type Inference
Kotlin strictly separates read-only variables from mutable state storage. The compiler infers data types automatically from value declarations.
// Single line comment /* Multi-line comment block */ val endpoint: String = "https://vidux.sh" // Immutable reference (read-only) var activeConnections = 10 // Mutable variable (type inferred as Int) // endpoint = "new-url" -> Compiler Error! val cannot be reassigned activeConnections += 1
val. Switch to var only when explicit state reassignment becomes necessary.
Core Types Hierarchy
In Kotlin, everything behaves as an object. There are no built-in primitive types like in Java; numbers and characters are handled as uniform objects.
Control Flows & Expressions
Conditionals function as expressions that return values. The structural when block acts as an optimized, powerful replacement for the classic switch construct.
val statusCode = 200 // 'if' used cleanly as an inline expression val statusMessage = if (statusCode == 200) "Success" else "Error" // 'when' matching block expression structure val routingResult = when (statusCode) { 200, 201 -> "Payload Processed" in 400..499 -> "Client Malformed Request" else -> "Unknown Network State" }
Loops & Ranges
Kotlin uses readable, expressive range constructs within its execution blocks to traverse sequences, arrays, and standard interval fields seamlessly.
// Iteration over inclusive range sequences (1 to 3) for (i in 1..3) { println("Index metric: $i") // String interpolation syntax } // Iterating down with explicit step sizing intervals for (x in 6 downTo 2 step 2) { println("Step value: $x") } // Standard collection tracking loops val items = listOf("prod-1", "prod-2") for (item in items) { println(item) }
Functions & Named Arguments
Functions support optional default argument values, which helps reduce boilerplates and prevents the need for overly nested method overloading.
// Standard function syntax with a default parameter fallback fun initializeConfig(timeout: Int, verbose: Boolean = false): String { return "Config targets: timeout=$timeout, debugging=$verbose" } // Shorthand single-expression function representation fun calculateSquare(n: Int) = n * n fun main() { // Invocation using clear named arguments out of order initializeConfig(verbose = true, timeout = 5000) }
Classes & Data Classes
Classes are closed by default (not inheritable). The data class keyword automatically generates fields like equals(), hashCode(), and toString() for pure data holders.
// Immutable data model schema template data class UserProfile(val id: Long, val username: String, var bio: String) class NetworkService(val baseUri: String) { fun connect() { println("Connecting to $baseUri") } } fun main() { val profile = UserProfile(1L, "vidux", "Software dev") val service = NetworkService("https://vidux.sh") // No 'new' keyword required! }
open modifier keyword**. By default, inheritance structures are safely locked.
Null Safety Ecosystem
Kotlin addresses the infamous billion-dollar mistake by separating nullable types from non-nullable ones at the compiler level, effectively eliminating NullPointerException risks.
var secureToken: String = "abc" // secureToken = null -> Compiler Error! Non-nullable types cannot hold null var sessionKey: String? = "xyz" sessionKey = null // Valid configuration using the nullable flag operator '?' // Safe call navigation execution chain returning length or null val keyLength = sessionKey?.length // Elvis Operator validation providing a fallback value if expression is null val definitiveLength = sessionKey?.length ?: 0
Asynchronous Coroutines
Kotlin manages non-blocking, asynchronous tasks using ultra-lightweight threads called Coroutines, which allow you to write clean, sequential-looking code for background routines.
import kotlinx.coroutines.* // 'suspend' marks asynchronous functions that can pause and resume execution suspend fun fetchRemotePayload(): String { delay(1000L) // Non-blocking delay thread block simulation return "Remote Dataset Response" } fun main() = runBlocking { launch { val payload = fetchRemotePayload() println(payload) } }