Android Development : 02 :Kotlin , The basics

Table of contents

Why use Kotlin:
1. Complete null safety :
Kotlin has built-in null safety (?
operator), which helps avoid NullPointerException
(the "billion-dollar mistake").
var name: String? = null // Safe in Kotlin
In Java, you'd need to add many null checks manually.
NullPointerException
Null Safety
NullPointerException
at compile time by making it clear which variables can be null and which cannot. In Java, any object reference can be null
, and using it without checking causes a crash (NullPointerException
). Kotlin eliminates this issue using nullable and non-nullable types.In Kotlin:
Non-nullable type:
it cannot hold a
null
valueDeclared without a
?
(built in null safety operator)Compiler won’t allow null assignment
var name: String = "John"
// name = null ❌ Compile-time error
Nullable type:
it can hold a
null
valueDeclared with a
?
Can store either a value or
null
var name: String? = "John"
name = null ✅ // allowed
There are 3 type of operators:
a. Safe Call (?.
)
println(name?.length) // Returns null if name is null
b. Elvis Operator (?:
)
val length = name?.length ?: 0 // If name is null, use 0
c. Not-null Assertion (!!
)
println(name!!.length) // Throws NPE if name is null (use with caution)
d. Safe Cast (as?
)
val obj: Any? = "Hello"
val str: String? = obj as? String
Null safety means Kotlin code won’t be even compile if we try to acess an element on null object.
Nullable objects are created explicitly in Kotlin
2.Use All Java Libraries in Kotlin too:
- Kotlin is 100% interoperable with Java. You can call Java code from Kotlin and vice versa.
3.Kotlin has coroutine:
- Kotlin provides coroutines to write async code easily and more clearly than Java's
AsyncTask
or callbacks.
GlobalScope.launch {
val data = fetchData()
}
4.Google support:
Has official support of Google. Since 2017, Google has made Kotlin the preferred language for Android development.
Jetpack Compose (modern UI toolkit) is built with Kotlin in mind.
5. Less code in Kotlin:
Kotlin is more compact .
Kotlin reduces boilerplate code significantly.
Less code = fewer bugs + better readability.
Programming with Kotlin:
Function:
A function is a segment of a program that performs a specific task. Your program may have one or more functions.
Define a function vs Calling a function :In your code, you define a function first. That means you specify all the instructions needed to perform that task.
Once the function is defined, then you can call that function, so the instructions within that function can be performed or executed.
Function names should follow the camel case convention, where the first word of the function name is all lower case. If there are multiple words in the name, there are no spaces between words, and all other words should begin with a capital letter.
There should be a space before the opening curly brace.
Variable:
In the apps that you use on your phone, notice that some parts of the app stay the same, while other parts change. For example, the names of the categories within the Settings app stay the same – Network & internet, Connected devices, Apps, and more. On the other hand, if you look at a news app, the articles will change often. The article name, source, time posted, and images change.
How do you write your code so that content changes over time? You can't rewrite the code in your app every time there are new articles to post, which happens every day, every hour, and every minute!
In this codelab, you learn how to write code that uses variables so that certain parts of your program can change without having to write a whole new set of instructions.
fun main() { val count: Int = 2 println(count) }
The Kotlin compiler knows that you want to store
2
(a whole number integer) into the variablecount
, so it can infer that thecount
variable is of typeInt
. Convenient, right? This is one example of how writing Kotlin code is more concise!fun main() { val count= 2 println(count) }
Note: If you don't provide an initial value when you declare a variable, you must specify the type.
In this line of code, no initial value is provided, so you must specify the data type:
val count: Int
In this line of code, an assigned value is provided, so you can omit the data type:
val count = 2
fun main() {
val numberOfPhotos = 100
val photosDeleted = 10
println("$numberOfPhotos photos")
println("$photosDeleted photos deleted")
println("${numberOfPhotos - photosDeleted} photos left")
}
Var vs Val:
Val:
Immutable Reference
Stands for "value"
Read-only variable (like
final
in Java) {both prevents reassignment, which is the same idea.}You cannot reassign a new value once it's set
final int x = 10;
x = 20; // ❌ Error
val x = 10
x = 20 // ❌ Error
However, just like in Java, if val
refers to a mutable object, the contents can still change:
val list = mutableListOf(1, 2)
list.add(3) // ✅ Allowed
list = listOf(4) // ❌ Error: Val cannot be reassigned
Var:
Mutable Reference
Stands for "variable"
Mutable variable — you can reassign it
var age = 25
age = 26 // ✅ Allowed
Feature | val | var |
Mutability | Immutable (read-only) | Mutable (can be updated) |
Reassignment | Not allowed | Allowed |
Use Case | Constants, fixed values | Changing values |
Array :
- declarations: arrayOf()
val numbers = arrayOf(1, 2, 3, 4)
val names = arrayOf("Alice", "Bob") // using arrayOf()
val squares = Array(5) { i -> i * i } //Using Array<Type>(size) { initializer }
// Output: [0, 1, 4, 9, 16] //Useful when you want to fill the array using logic or calculations.
val intArray = intArrayOf(1, 2, 3) //Using Specific Type Arrays
val charArray = charArrayOf('A', 'B')
val booleanArray = booleanArrayOf(true, false)
val mixed = arrayOf(1, "Hello", 3.14) // Array of Any type
printf(numbers[2]) // to get the number at possition 2 of numbers array as the output
- In Kotlin,
numbers.joinToString()
is a convenient way to convert an array or list into a single string, with each element separated by a comma by default.
val numbers = arrayOf(1, 2, 3, 4, 5)
println(numbers.joinToString()) // output : 1,2,3,4,5
Type Checks in Kotlin :
Kotlin uses the
is
keyword to check if an object is of a specific type.Syntax;
if (x is String) {
println(x.length) // Smart cast: x is automatically cast to String
}
If the
is
check passes, Kotlin automatically casts the object to that type within theif
block.Opposite : Use
!is
to check if it’s not of s type:
if (x !is Int) {
println("x is not an Int")
}
Type Casts in Kotlin :
Kotlin provides two type casting operators:
as
andas?
.Unsafe cast:(
as
) If the cast is not possible, it throws a ClassCastException:
val x: Any = "Hello"
val y: String = x as String // Works fine
val x: Any = 123
val y: String = x as String // ❌ Throws exception at runtime
- Safe cast:(
as?
) Returns the casted value ornull
if the cast fails:
val x: Any = 123
val y: String? = x as? String // ✅ Returns null, doesn't crash
- Use safe casts when you're unsure of the type and want to avoid exceptions.
Operation | Keyword | Safe? | Returns |
Type check | is / !is | ✅ | Boolean |
Unsafe cast | as | ❌ | Casted value or throws |
Safe cast | as? | ✅ | Casted value or null |
For loop in Kotlin :
declarations:
//Loop Through a Range:1..5 creates a range from 1 to 5 (inclusive).
for (i in 1..5) {
println(i) // Prints 1 to 5
}
//Loop With Step
for (i in 1..10 step 2) {
println(i) // Prints 1, 3, 5, 7, 9
}
//Loop in Reverse
for (i in 5 downTo 1) {
println(i) // Prints 5, 4, 3, 2, 1
}
//Loop Over an Array or List
val fruits = arrayOf("Apple", "Banana", "Cherry")
for (fruit in fruits) {
println(fruit)
}
OOPs Concepts in Kotlin:
Feature | Procedural Programming | Object-Oriented Programming (OOP) |
Focus | Functions / Procedures | Objects / Classes |
Data and Function | Separate | Combined in objects |
Reusability | Limited | High through inheritance and polymorphism |
Encapsulation | Not supported | Supported |
- Kotlin fully supports Object-Oriented Programming (OOP) concepts, just like Java. In fact, Kotlin is designed to be both object-oriented and functional, so it combines the best of both paradigms.
Class and Objects:
Kotlin allows you to define classes and create objects.
A class is a blueprint for creating objects. It defines properties (variables) and behaviors (functions).
An object is an instance of a class — created using the
class
blueprint.
class Car(val brand: String, val model: String) {
fun start() {
println("$brand $model is starting...")
}
}
val myCar = Car("Toyota", "Camry")
myCar.start()
Inheritance:
Kotlin supports class inheritance using the
open
keyword (because classes are final by default).
open class Animal {
fun eat() = println("Eating...")
}
class Dog : Animal() {
fun bark() = println("Barking...")
}
Encapsulation:
You can control access to properties/methods using visibility modifiers:
private
,protected
,internal
, andpublic
.
class Person {
private var age: Int = 0
fun setAge(a: Int) {
age = a
}
}
Polymorphism:
Supports method overriding and interface implementation.
open class Shape {
open fun draw() = println("Drawing shape")
}
class Circle : Shape() {
override fun draw() = println("Drawing circle")
}
Abstraction:
You can use abstract classes and interfaces.
abstract class Animal {
abstract fun makeSound()
}
class Cat : Animal() {
override fun makeSound() = println("Meow")
}
Subscribe to my newsletter
Read articles from Dibyashree Chakravarty directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
