Kotlin for Android

The modern language for Android — concise, safe, and fully interoperable with Java

Syntax Null Safety Classes Collections

Table of Contents

Kotlin Overview

Kotlin is Google's preferred language for Android development. It reduces boilerplate compared to Java, eliminates most null pointer exceptions at compile time, and works seamlessly with existing Java code and Android APIs.

Java Code ←→ Kotlin Code (100% interoperable) ↓ Android SDK / Jetpack Libraries ↓ Android App
FeatureBenefit for Android
Concise syntaxLess code in Activities, ViewModels, adapters
Null safetyFewer crashes from null references
Data classesPerfect for API models and Room entities
CoroutinesClean async code for network and database
Extension functionsAdd helpers to Android classes without subclassing

1Kotlin Syntax

Kotlin syntax is clean and expressive. Semicolons are optional, types can often be inferred, and string templates make formatting easy.

Hello World and basic structure

Kotlin — Main.ktfun main() { println("Hello, Android!") }

Comments, strings, and templates

Kotlin — Syntax basics// Single-line comment /* Multi-line comment */ val name = "Nikhil" val greeting = "Hello, $name!" // string template val details = "User: ${name.uppercase()}" // expression in template val multiline = """ Line 1 Line 2 """.trimIndent()

Control flow

Kotlin — if, when, loops// if as expression val status = if (score >= 50) "Pass" else "Fail" // when — powerful switch replacement val label = when (networkType) { "WIFI" -> "Connected via Wi-Fi" "MOBILE" -> "Connected via Mobile Data" else -> "No connection" } // for loop for (i in 1..5) println(i) for (item in items) println(item) // while loop while (retryCount < 3) { retryCount++ }

Kotlin vs Java syntax

JavaKotlin
String name = "Nikhil";val name = "Nikhil"
if-else blocksif-else as expression
switch (x) { ... }when (x) { ... }
System.out.println()println()
new ArrayList<>()mutableListOf()

2Variables

Kotlin uses val for read-only values and var for mutable variables. Prefer val by default — immutability makes code safer and easier to reason about.

val vs var

Kotlin — Variable declarationsval appName = "LearnHub" // read-only, cannot reassign var loginCount = 0 // mutable, can reassign loginCount = 1 // Explicit types (optional when inferred) val maxRetries: Int = 3 var userName: String = "Guest"

Basic types

TypeExampleAndroid Use
Int42IDs, counts, resource IDs
Long1_000_000LTimestamps
Double / Float3.14Coordinates, ratings
BooleantrueFeature flags, toggles
String"Hello"UI text, API fields
Char'A'Single characters

Type conversion

Kotlin — Safe type conversionval countStr = "42" val count = countStr.toInt() // String → Int val price = 99.99 val priceInt = price.toInt() // truncates to 99 // Android example — parse EditText input val ageText = binding.etAge.text.toString() val age = ageText.toIntOrNull() ?: 0 // safe parse with default

Constants

Kotlin — Companion object constantsclass ApiConfig { companion object { const val BASE_URL = "https://api.example.com/" const val TIMEOUT_SECONDS = 30 } } // Top-level constant const val APP_TAG = "LearnHub"

3Functions

Kotlin functions are declared with fun. They support default parameters, named arguments, single-expression bodies, and higher-order functions — reducing boilerplate throughout Android code.

Basic and single-expression functions

Kotlin — Function syntaxfun greet(name: String): String { return "Hello, $name!" } // Single-expression — return type inferred fun add(a: Int, b: Int) = a + b fun isNetworkAvailable(context: Context): Boolean { // implementation... return true }

Default and named parameters

Kotlin — Default parametersfun showToast( context: Context, message: String, duration: Int = Toast.LENGTH_SHORT ) { Toast.makeText(context, message, duration).show() } // Named arguments — skip order, improve readability showToast(context = this, message = "Saved!", duration = Toast.LENGTH_LONG)

Extension functions

Kotlin — Extend existing classesfun View.visible() { visibility = View.VISIBLE } fun View.gone() { visibility = View.GONE } fun String.isValidEmail(): Boolean { return android.util.Patterns.EMAIL_ADDRESS.matcher(this).matches() } // Usage in Activity: binding.progressBar.gone() binding.content.visible()

Lambda and higher-order functions

Kotlin — Lambdas// Lambda as parameter fun fetchData(onSuccess: (String) -> Unit, onError: (Exception) -> Unit) { try { onSuccess("Data loaded") } catch (e: Exception) { onError(e) } } // Usage — trailing lambda syntax fetchData( onSuccess = { data -> println(data) }, onError = { e -> println(e.message) } ) // Shorthand when lambda is last parameter button.setOnClickListener { viewModel.onButtonClick() }

4Classes

Kotlin classes are concise. Primary constructors, data classes, objects, and sealed classes cover most Android patterns — from API models to UI state and singletons.

Class with primary constructor

Kotlin — User classclass User( val id: Int, var name: String, val email: String ) { fun displayName(): String = name.uppercase() override fun toString(): String = "User(id=$id, name=$name)" }

Data class — API models

Kotlin — Post data classdata class Post( val id: Int, val title: String, val body: String, val userId: Int = 0 ) // Auto-generated: equals(), hashCode(), toString(), copy() val post = Post(1, "Hello", "World") val updated = post.copy(title = "Updated Title")

Inheritance and interfaces

Kotlin — open class and overrideopen class Animal(val name: String) { open fun speak(): String = "..." } class Dog(name: String) : Animal(name) { override fun speak(): String = "Woof!" } interface ClickListener { fun onClick() fun onLongClick(): Boolean = false // default implementation } class MyButton : ClickListener { override fun onClick() { /* handle click */ } }

Object and companion object

Kotlin — Singleton and factory// Singleton object NetworkManager { fun isConnected(context: Context): Boolean { /* ... */ return true } } // Companion object — static-like members class TaskRepository private constructor() { companion object { @Volatile private var instance: TaskRepository? = null fun getInstance(): TaskRepository { return instance ?: synchronized(this) { instance ?: TaskRepository().also { instance = it } } } } }

Sealed class — UI state

Kotlin — Sealed class for statesealed class UiState { object Loading : UiState() data class Success(val data: List<Task>) : UiState() data class Error(val message: String) : UiState() } // Exhaustive when — compiler ensures all cases handled fun render(state: UiState) = when (state) { is UiState.Loading -> showProgressBar() is UiState.Success -> showList(state.data) is UiState.Error -> showError(state.message) }

5Null Safety

Kotlin's type system distinguishes nullable and non-nullable types at compile time. This eliminates most NullPointerException crashes — the number one cause of Android app failures.

Nullable vs non-nullable types

Kotlin — Null typesvar name: String = "Nikhil" // cannot be null var nickname: String? = null // can be null // name = null // COMPILE ERROR nickname = null // OK

Safe call and Elvis operator

Kotlin — ?. and ?: operatorsval length = nickname?.length // returns null if nickname is null val display = nickname ?: "Anonymous" // Elvis — default if null val count = nickname?.length ?: 0 // Android example val email = intent.getStringExtra("email") ?: "" binding.tvEmail.text = user?.email?.uppercase() ?: "No email"

let, also, apply, run, with

Kotlin — Scope functions// let — execute block if not null user?.let { u -> binding.tvName.text = u.name binding.tvEmail.text = u.email } // apply — configure object, return object val intent = Intent(this, DetailActivity::class.java).apply { putExtra("id", taskId) putExtra("title", title) } // also — side effect, return object val result = fetchData().also { Log.d("API", "Got ${it.size} items") }

Safe casts and not-null assertion

Kotlin — as? and !!// Safe cast — returns null if wrong type val fragment = supportFragmentManager.findFragmentById(R.id.container) as? MyFragment // Not-null assertion — use only when 100% sure (avoid !! in production) val name = nickname!! // throws NPE if null // Prefer explicit check if (nickname != null) { println(nickname.length) // smart cast — Kotlin knows it's not null }

6Collections

Kotlin provides rich collection types — List, Set, Map — with read-only and mutable variants, plus powerful functional operations for filtering, mapping, and sorting API data.

Creating collections

Kotlin — List, Set, Map// Read-only (immutable interface) val fruits = listOf("Apple", "Banana", "Mango") val uniqueIds = setOf(1, 2, 3) val userMap = mapOf("name" to "Nikhil", "role" to "Developer") // Mutable val tasks = mutableListOf<Task>() tasks.add(Task(1, "Learn Kotlin")) tasks.removeAt(0) val scores = mutableMapOf<String, Int>() scores["Alice"] = 95 scores["Bob"] = 87

Functional operations

Kotlin — map, filter, sortedBydata class Task(val id: Int, val title: String, val completed: Boolean) val tasks = listOf( Task(1, "Learn Kotlin", true), Task(2, "Build App", false), Task(3, "Publish", false) ) val pendingTitles = tasks .filter { !it.completed } .sortedBy { it.title } .map { it.title } val completedCount = tasks.count { it.completed } val firstPending = tasks.firstOrNull { !it.completed }

Collections in Android

Kotlin — RecyclerView adapter dataclass TaskAdapter : RecyclerView.Adapter<TaskViewHolder>() { private val items = mutableListOf<Task>() fun submitList(newTasks: List<Task>) { items.clear() items.addAll(newTasks) notifyDataSetChanged() } override fun getItemCount() = items.size override fun onBindViewHolder(holder: TaskViewHolder, position: Int) { holder.bind(items[position]) } }

Collection types summary

Read-onlyMutableFactory Function
List<T>MutableList<T>listOf() / mutableListOf()
Set<T>MutableSet<T>setOf() / mutableSetOf()
Map<K,V>MutableMap<K,V>mapOf() / mutableMapOf()

7Kotlin for Android

Kotlin integrates deeply with Android APIs and Jetpack libraries. These patterns appear in nearly every modern Android project — from Activities and Fragments to ViewModels, coroutines, and Compose.

Activity with View Binding

Kotlin — MainActivity.ktclass MainActivity : AppCompatActivity() { private lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) binding.btnSubmit.setOnClickListener { val name = binding.etName.text.toString().trim() if (name.isNotEmpty()) { viewModel.saveUser(name) } else { binding.etName.error = "Name required" } } } }

ViewModel with coroutines

Kotlin — ViewModel + coroutinesclass UserViewModel( private val repository: UserRepository = UserRepository() ) : ViewModel() { private val _users = MutableLiveData<List<User>>() val users: LiveData<List<User>> = _users fun loadUsers() { viewModelScope.launch { try { _users.value = repository.fetchUsers() } catch (e: Exception) { Log.e("UserVM", "Failed to load", e) } } } }

Intent extras with Kotlin

Kotlin — Intent helpers// Start Activity with extras fun Context.openDetail(taskId: Int, title: String) { startActivity(Intent(this, DetailActivity::class.java).apply { putExtra("task_id", taskId) putExtra("title", title) }) } // Receive in DetailActivity class DetailActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val taskId = intent.getIntExtra("task_id", -1) val title = intent.getStringExtra("title") ?: "" } }

Property delegates

Kotlin — by viewModels(), by lazyclass TaskFragment : Fragment() { private val viewModel: TaskViewModel by viewModels() private val adapter by lazy { TaskAdapter() } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.recyclerView.adapter = adapter viewModel.tasks.observe(viewLifecycleOwner) { tasks -> adapter.submitList(tasks) } } }

Common Android Kotlin patterns

PatternKotlin FeatureExample
API modeldata classdata class User(val id: Int, val name: String)
UI statesealed classsealed class UiState { ... }
Click listenerLambdabutton.setOnClickListener { ... }
ViewModel accessDelegateby viewModels()
Async workCoroutinesviewModelScope.launch { ... }
Null-safe UI?. / ?:user?.name ?: "Guest"

8Hands-On Exercises

1

Write a Kotlin program using syntax basics — variables, when, loops, and string templates.

2

Declare variables with val and var. Parse user input from an EditText safely with toIntOrNull().

3

Create functions with default parameters and an extension function View.visible() / View.gone().

4

Define a data class for a Task, a sealed class for UI state, and a singleton object for app config.

5

Practice null safety — use ?., ?:, and let to handle nullable API response fields.

6

Filter, map, and sort a list of tasks using collection operations. Display results in a RecyclerView.

7

Build a simple Android screen using Kotlin for Android — View Binding, by viewModels(), and LiveData observation.

Kotlin for Android MCQ Practice

10 Basic MCQs 10 Advanced MCQs

10 Basic Kotlin for Android MCQs

1

val vs var?

AIdentical
Bval immutable reference; var mutable
Cvar read-only
Dval mutable
Explanation: val cannot reassign; object may still be mutable.
2

Null safety — String? means?

AEmpty string
BNon-null always
CNullable String type
DDeprecated
Explanation: Must check before use or use safe calls ?.
3

data class provides?

AGPS
BSQL mapping only
CLayout inflation
Dequals, hashCode, toString, copy automatically
Explanation: Ideal for model/DTO classes.
4

fun keyword defines?

AFunction
BVariable
CClass only
DInterface only
Explanation: Functions are first-class in Kotlin.
5

Safe call operator?

A!! force unwrap safe
B?. calls only if not null
CCreates thread
DSQL query
Explanation: user?.name returns null if user is null.
6

when expression?

AImport statement
BLoop only
CEnhanced switch matching values/types
DGradle task
Explanation: when (x) { is String -> ... else -> ... }
7

lateinit used for?

ASQL
BNullable fields
CConstants
DNon-null var initialized later
Explanation: lateinit var binding: ActivityMainBinding — must assign before use.
8

Object keyword creates?

ASingleton or anonymous object
BArray only
CXML layout
DManifest
Explanation: object Repository { } is singleton.
9

Extension function?

AOverride private method
BAdd function to existing class without inheritance
CJava only
DDeprecated
Explanation: fun String.capitalizeWords(): String { ... }
10

Google recommends Kotlin because?

ANo Java interop
BReplaces Linux
CConcise, null-safe, official Android language
DSmaller APK always
Explanation: Kotlin is preferred for new Android projects since 2019.

10 Advanced Kotlin for Android MCQs

11

Sealed class?

AOpen to all subclasses globally
BRestricted class hierarchy — exhaustive when
CSQL table
DService type
Explanation: sealed class Result { object Loading; data class Success(val data: T) }
12

Inline function?

AJava incompatible
BAlways slower
CCopies bytecode at call site — reduces lambda overhead
DDeprecated
Explanation: inline fun with higher-order functions like let scope.
13

Coroutines launch vs async?

Alaunch SQL only
BSame
Casync UI only
Dlaunch: fire-and-forget Job; async: returns Deferred result
Explanation: async { compute() }.await() for parallel results.
14

Companion object?

AStatic-like members on class
BMultiple per class
CReplaces constructor
DManifest entry
Explanation: Companion object Factory { fun create() }
15

Delegation by?

AInheritance only
BImplements interface forwarding to delegate instance
CGPS
DRoom
Explanation: class RepoImpl(r: Remote) : Repo by r
16

Reified type parameter?

AJava feature
BAll generics reified
CAccess generic type at runtime with inline
DSQL only
Explanation: inline fun Gson.fromJson() used with inline.
17

Scope functions let/apply/run?

ALayout only
BAll identical
CDeprecated
Dlet: it lambda result; apply: this configure; run: block result
Explanation: apply returns receiver; let passes as it.
18

Higher-order function?

ATakes or returns another function
BOnly top-level
CBanned on Android
DJNI only
Explanation: list.filter { it.active } — lambda parameter.
19

Kotlin interop with Java?

AImpossible
B100% bidirectional — @JvmStatic, @Nullable annotations
CKotlin only modules
DNo annotations
Explanation: Android projects mix Kotlin and Java freely.
20

Immutable list?

AArray fixed size only
BmutableListOf read-only
ClistOf() returns read-only List
DNo lists in Kotlin
Explanation: mutableListOf for modifications; listOf for fixed collections.
Click an option to select, then check answers.

Kotlin for Android Interview Q&A

15 topic-focused questions for interviews and revision.

1val vs var with example.easy
Answer: val pi = 3.14 // cannot reassign; var count = 0; count++ // OK
2Explain null safety.easy
Answer: Types add ? for nullable; safe call ?.; Elvis ?: default; !! only when certain non-null.
3data class benefit on Android.easy
Answer: Parcelable models, JSON mapping, copy for updates, equals for DiffUtil.
4when vs if-else chain.easy
Answer: when exhaustive with sealed classes; cleaner multi-branch logic.
5lateinit vs lazy.medium
Answer: lateinit var for inject/bind later; lazy val computed on first access.
6Extension function example.medium
Answer: fun View.visible() { visibility = View.VISIBLE } — readable UI helpers.
7Object singleton use.easy
Answer: object ApiClient { val retrofit = ... } — single shared instance.
8Sealed class for UI state.medium
Answer: sealed class UiState { object Loading; data class Error(val msg: String); data class Data(val list: List) }
9Kotlin collections map filter.easy
Answer: users.filter { it.active }.map { it.name } — functional chain.
10Companion object factory.medium
Answer: class User private constructor(val id: Int) { companion object { fun from(id: Int) = User(id) } }
11Why Kotlin for Android?easy
Answer: Less boilerplate, null safety, coroutines, data classes, Google official support.
12Java calling Kotlin.medium
Answer: Use @JvmName, @JvmStatic on companion; mind nullable types become platform types.
13Scope function choose apply vs also.hard
Answer: apply: configure object, returns this. also: side effect logging, returns this.
14Immutable by default pattern.medium
Answer: Prefer val, read-only lists, copy() for updates instead of mutating shared state.
15Common Kotlin Android mistake.medium
Answer: Using !! excessively; blocking main thread; lateinit before init; GlobalScope misuse.