Skip to main content

Types and variables

val, var, and inference​

Use val for a read-only reference and var when the reference must be reassigned.

val userId: Long = 42L
val displayName = "Rakesh" // inferred String
var retryCount = 0 // inferred Int
retryCount += 1

Prefer val: fewer changing references mean fewer possible program states. Use var only when reassignment represents a real transition.

val does not mean immutable​

val names = mutableListOf("Ada")
names += "Grace" // object changes
// names = mutableListOf("Linus") // reference cannot change

val protects the reference, not the referenced object's internal state. For true immutability, the object's API must prevent observable mutation.

Common Kotlin types​

TypeExampleDetail
Int4232-bit signed integer
Long42L64-bit; suffix matters
Float3.5F32-bit floating point
Double3.5Default decimal type
BooleantrueConditions must be explicitly true or false; 0 and 1 are not Boolean values
Char'A'Not a String
String"Android"Immutable character sequence

In Kotlin code, these all look and behave like normal types. Behind the scenes, the JVM can store many non-null numbers and booleans as efficient primitive values. You usually do not need to think about that optimization while writing ordinary application code.

Why numbers are not booleans​

Kotlin requires every condition to produce a Boolean:

val count = 1

// if (count) { } // Compilation error
if (count > 0) {
println("At least one item")
}

Kotlin does not guess that 0 means false or that a nonzero number means true. You must write the rule you actually mean: count > 0, value != 0, or value == 1.

If a database or old API uses 1 and 0, convert it explicitly:

val databaseValue = 1
val isEnabled: Boolean = databaseValue == 1

Kotlin requires explicit numeric conversion​

An Int and a Long are different types. Although every Int value fits inside a Long, Kotlin does not silently widen an Int during assignment.

val count: Int = 10

// val total: Long = count // Compilation error
val total: Long = count.toLong()

count.toLong() creates the Long value 10L. In simple terms: Kotlin makes you say when you want a different numeric type instead of silently guessing.

Mixed arithmetic is different​

Kotlin can select an arithmetic operation based on both operands:

val count: Int = 10
val price: Long = 100L
val total = count + price

println(total) // 110

Here, total is a Long because the addition includes a Long. This is a new arithmetic result; it is not a direct assignment of the original Int to a Long variable.

Open in Kotlin Playground

Arithmetic overflow is a separate problem​

Conversion and overflow are different:

  • Conversion: changing a value from one numeric type to another, such as Int to Long.
  • Overflow: producing a number that is too large or too small for the type doing the calculation.

The largest Int is 2,147,483,647. Adding one exceeds the Int range:

val maximum = Int.MAX_VALUE
val overflowed = maximum + 1

println(maximum) // 2147483647
println(overflowed) // -2147483648

On the JVM, ordinary Int arithmetic wraps around instead of throwing automatically.

Convert before the calculation​

val safe: Long = Int.MAX_VALUE.toLong() + 1
println(safe) // 2147483648

The conversion happens first, so addition uses Long arithmetic and this result fits.

Converting afterward is too late:

val wrong: Long = (Int.MAX_VALUE + 1).toLong()
println(wrong) // -2147483648

The calculation inside the parentheses happens first. Both operands are Int, so the result overflows as an Int. Calling .toLong() afterward only converts the already-wrong value.

Android and backend scenario

Counts, file sizes, time durations, prices in minor units, and pagination offsets may originate outside your code. Validate their permitted ranges and perform calculations in a sufficiently wide type. For calculations where overflow must fail rather than wrap, use checked operations such as Java's Math.addExact and handle ArithmeticException.

Open in Kotlin Playground
Interview-ready answer

Kotlin does not automatically assign an Int to a Long; use toLong(). Conversion order matters: if an Int calculation overflows first, converting its result to Long cannot repair it. Convert an operand before the calculation when the result needs Long range.

Public API guidance​

For short local code, inferred types are usually easy to read. For public functions and properties, writing the type explicitly often makes the API clearer and prevents an internal edit from unexpectedly changing what callers receive.

Open in Kotlin Playground

Quick check​

Can the contents referenced by a val change?

Yes, if the referenced object exposes mutation. Only reassignment of the variable is prohibited.