In Kotlin, you usually define constructors and initialize properties directly in the class header using a primary constructor.
1. Primary constructor
The most common style is:
class Person(val name: String, var age: Int)
This defines:
- a class named
Person - a read-only property
name - a mutable property
age - a constructor that requires both values
Usage:
fun main() {
val person = Person("Alice", 30)
println(person.name)
println(person.age)
person.age = 31
println(person.age)
}
Here, val name: String and var age: Int are both constructor parameters and class properties.
2. Constructor parameters without properties
If you omit val or var, the parameter is only available during initialization:
class Person(name: String) {
val uppercaseName = name.uppercase()
}
Usage:
fun main() {
val person = Person("Alice")
println(person.uppercaseName)
}
In this example, name is not a property. You cannot access person.name unless you declare it with val or var.
3. Initialize properties in the class body
You can initialize properties using constructor values:
class Rectangle(val width: Int, val height: Int) {
val area: Int = width * height
}
Usage:
fun main() {
val rectangle = Rectangle(5, 4)
println(rectangle.area)
}
Output:
20
4. Use an init block
If you need validation or setup logic, use an init block:
class User(val username: String, val age: Int) {
init {
require(username.isNotBlank()) {
"Username must not be blank"
}
require(age >= 0) {
"Age must not be negative"
}
}
}
The init block runs when an object is created:
fun main() {
val user = User("kotlinFan", 25)
println(user.username)
}
5. Default constructor values
You can give constructor parameters default values:
class Product(
val name: String,
val price: Double = 0.0,
val inStock: Boolean = true
)
Usage:
fun main() {
val freeSample = Product("Sticker")
val laptop = Product("Laptop", 999.99, false)
println(freeSample.price)
println(laptop.inStock)
}
6. Named arguments
Named arguments make constructor calls clearer:
class Book(
val title: String,
val author: String,
val pages: Int
)
fun main() {
val book = Book(
title = "Kotlin Basics",
author = "JetBrains",
pages = 250
)
println(book.title)
}
7. Secondary constructors
Kotlin also supports secondary constructors, but they are less common:
class Car {
val brand: String
val year: Int
constructor(brand: String, year: Int) {
this.brand = brand
this.year = year
}
}
Usage:
fun main() {
val car = Car("Toyota", 2024)
println(car.brand)
println(car.year)
}
However, this is usually better written with a primary constructor:
class Car(val brand: String, val year: Int)
8. Primary and secondary constructors together
If a class has a primary constructor, secondary constructors must delegate to it using this(...):
class Employee(val name: String, val role: String) {
constructor(name: String) : this(name, "Employee")
}
Usage:
fun main() {
val employee = Employee("Sam")
val manager = Employee("Dana", "Manager")
println(employee.role)
println(manager.role)
}
9. Late initialization with lateinit
For mutable non-null properties initialized later, use lateinit var:
class Session {
lateinit var token: String
fun start(token: String) {
this.token = token
}
}
Usage:
fun main() {
val session = Session()
session.start("abc123")
println(session.token)
}
Use lateinit carefully. Accessing it before initialization causes an exception.
10. Custom getters and setters
You can customize property access:
class Temperature(celsius: Double) {
var celsius: Double = celsius
set(value) {
require(value >= -273.15) {
"Temperature cannot be below absolute zero"
}
field = value
}
val fahrenheit: Double
get() = celsius * 9 / 5 + 32
}
Usage:
fun main() {
val temperature = Temperature(25.0)
println(temperature.fahrenheit)
temperature.celsius = 30.0
println(temperature.fahrenheit)
}
Quick summary
class Person(
val name: String,
var age: Int = 0
) {
init {
require(name.isNotBlank()) {
"Name cannot be blank"
}
}
val isAdult: Boolean
get() = age >= 18
}
This example shows:
val name: read-only property initialized from constructorvar age: mutable property with a default valueinit: validation logicisAdult: computed property
In most Kotlin code, prefer a primary constructor with val or var properties unless you specifically need more complex construction logic.
