Theory
The crash Kotlin was built to prevent
In BCA403, you met Java's most infamous crash: the NullPointerException, calling a method on a variable that turned out to be null. It strikes at RUNTIME, often in front of a user.
Kotlin's designers set out to KILL this bug, and largely did. In Kotlin, a variable CANNOT hold null unless you explicitly permit it, and the COMPILER enforces this. This lesson covers Kotlin's variables, its val/var distinction, and its signature feature: null safety, the single biggest reason to prefer Kotlin over Java. FestConnect Mobile's data will be crash-resistant by design.
Theory
val, var, and types
Kotlin has two variable keywords:
- val: read-only, assigned once (like Java's
final). Prefer this by default - var: mutable, can be reassigned
val fest = "TechnoUtsav" (cannot change); var seats = 350 (can). Types are usually INFERRED (val x = 5 is an Int), or declared explicitly (val x: Int = 5).
The types are familiar from Java: Byte, Short, Int, Long, Float (with an f suffix), Double, Boolean, Char (single quotes), String (double quotes, with $ templates). Preferring val makes code safer and clearer: it signals 'this will not change', which the compiler enforces.
Theory
Null safety: the signature feature
Here is Kotlin's defining idea. By default, a type cannot hold null:
val name: String = null is a COMPILE ERROR.
To allow null, you mark the type nullable with a ?:
val name: String? = null is fine.
This forces you to DECIDE, up front, whether a value can be null, and the compiler makes you handle the nullable case safely. To use a nullable value:
- safe call `?.`:
name?.lengthreturns the length, ornullif name is null (no crash) - Elvis `?:`:
name?.length ?: 0gives a DEFAULT (0) when null - not-null assertion `!!`:
name!!.lengthforces it, THROWING if null (use rarely)
Because nullability is in the TYPE and checked at compile time, most NullPointerExceptions become impossible.
Practical
Null safety in action
fun main() {
val fest: String = "TechnoUtsav" // non-null: cannot be null
// val bad: String = null // COMPILE ERROR
var nickname: String? = null // nullable: ? allows null
// Safe call: returns null instead of crashing
println(nickname?.length) // null (nickname is null)
nickname = "Techno"
println(nickname?.length) // 6
// Elvis operator: a default when null
val len = nickname?.length ?: 0 // 6 here; 0 if null
println(len)
}
Quiz
In Kotlin, what does val name: String = null cause?
- It works: name holds null
- A COMPILE ERROR: a non-nullable String cannot hold null; you must declare it String? to allow null
- A runtime NullPointerException
- name becomes an empty string
Show the answer
A COMPILE ERROR: a non-nullable String cannot hold null; you must declare it String? to allow null
By default Kotlin types are NON-NULLABLE, so assigning null to a String is a COMPILE ERROR, the compiler stops you before the program runs. To permit null you must mark the type nullable: String? (with the question mark). This compile-time enforcement is exactly how Kotlin eliminates most NullPointerExceptions: the danger is caught during compilation, not as a runtime crash. Option A is wrong (non-nullable rejects null). Option C describes JAVA's behaviour (null assigned, crash later); Kotlin moves the check EARLIER, to compile time. Option D invents a default. The core idea: nullability is part of the type, and the compiler enforces it, so null bugs surface early.
Think first
How Kotlin kills the NullPointerException
In Java (BCA403), a NullPointerException strikes at runtime when you call a method on a null. How does Kotlin's design prevent this from ever reaching a user? Then tap.
Show the answer
Kotlin makes NULLABILITY PART OF THE TYPE and enforces it at COMPILE TIME. A String cannot be null; only a String? can. And when you have a String?, the compiler REFUSES to let you call a method on it directly (name.length is an error on a nullable): you MUST handle the null case, using the safe call ?. (returns null instead of crashing), the Elvis operator ?: (a default), or the explicit !! (which you deliberately choose, accepting the risk). So the 'what if it is null?' question that Java lets you IGNORE until it crashes, Kotlin forces you to ANSWER while coding. The bug is caught during compilation, before the app ships, so it never reaches a user as a crash. Moving the check from runtime to compile time is the whole trick, and it is why null safety is Kotlin's flagship feature.
Watch out
Variable and null-safety traps
Reassigning a val: val is read-only; use var if it must change.
Overusing !!: the not-null assertion !! re-introduces the crash risk Kotlin removed; prefer ?. and ?:.
Forgetting the ? for genuinely nullable data: data from the network or a form may be null; type it as nullable and handle it.
Float without f: 3.5 is a Double; a Float needs 3.5f.
Defaulting to var: prefer val unless you need to reassign; it is safer and clearer.
Theory
Data is safe; now decisions
FestConnect Mobile's variables are now typed and null-safe. Next, the app needs to make DECISIONS: Kotlin's if and, especially, its powerful when expression (a supercharged switch), plus ranges. A Kotlin twist you will enjoy: if and when are EXPRESSIONS that return a value, not just statements. Conditionals come next, then arrays/lists and loops complete Kotlin's basics.
Summary
Key takeaways
- val is read-only (assign once, like Java final); var is mutable; prefer val by default.
- Types are usually inferred (val x = 5 is Int) or declared (val x: Int = 5); familiar set: Byte, Short, Int, Long, Float (f), Double, Boolean, Char, String.
- Null safety: by default a type CANNOT hold null; val name: String = null is a compile error.
- Mark a type nullable with ?: val name: String? = null allows null.
- Handle nullable values with the safe call ?. (null instead of crash), Elvis ?: (a default), or !! (forces, throws if null: rare).
- Nullability is in the type and checked at compile time, eliminating most NullPointerExceptions (Java's runtime crash).
- Memory hook: val over var, ? to allow null, ?. and ?: to handle it safely, !! only when sure.