Why is `val x = 1` inferred as `Int` but you might need `val x: Long = 1`? Explain integer literal types and how to force `Long`.
answer
- Undecorated int literal = Int by default
- L suffix or annotation for Long
- Too big for Int -> auto Long
- No implicit widening; use toLong()
- 1.0 is Double, 1.0f is Float
basics
~20 sA plain number like 1 is treated as an Int by default. If you need a Long, either write the type (val x: Long = 1) or add an L suffix (1L). The value is the same; the type differs.
solid answer
~50 sAn undecorated integer literal has the **default type `Int`** when it fits in 32 bits, so `val x = 1` is `Int`. To get a `Long` you either annotate the variable (`val x: Long = 1`, where the literal `1` is treated as `Long` in that context) or use the `L` suffix (`val x = 1L`, which makes the literal itself a `Long`). If a literal is too big for `Int` but fits in 64 bits, it's inferred as `Long` automatically. This matters because `Int` and `Long` are distinct types: Kotlin does **not** implicitly widen, so passing an `Int` where a `Long` is expected won't compile — you call `.toLong()`. The same pattern applies to floating literals: `1.0` is `Double`; for `Float` you write `1.0f` or annotate `val x: Float = 1.0f`. Other literal aids: underscores for readability (`1_000_000`), `0x`/`0b` prefixes, and `u`/`U` for unsigned types (`1u` is `UInt`).
code
kotlin · 6 linesval a = 1 // Int
val b = 1L // Long (suffix)
val c: Long = 1 // Long (annotation)
val big = 3_000_000_000 // Long (overflows Int)
val i = 1
val l: Long = i.toLong() // explicit widening requiredgo deeper
Knows 1 is Int and that you add L or annotate for Long.
Explains default literal types, automatic Long promotion for big literals, and the suffix family.
Articulates the no-implicit-widening design decision and its interaction with Java/DB Long APIs.
Weighs correctness/overflow risk in API design and recommends conventions (annotate ids/timestamps as Long).
## Default integer literal type An integer literal without a suffix gets the **smallest fitting default**: - Fits in `Int` (−2³¹ … 2³¹−1) → **`Int`** (the default). - Doesn't fit `Int` but fits `Long` → **`Long`** automatically. ```kotlin val a = 1 // Int val b = 3_000_000_000 // Long (too big for Int) ``` ## Forcing `Long` two ways ```kotlin val c: Long = 1 // explicit annotation; literal 1 typed as Long here val d = 1L // L suffix makes the literal itself Long ``` Both give the value 1 with type `Long`; pick whichever reads better. In APIs returning timestamps/ids, `1L`/annotation prevents accidental `Int` overflow. ## No implicit widening Kotlin deliberately **does not** auto-convert smaller numeric types to larger ones: ```kotlin val i = 1 // Int // val l: Long = i // ERROR: Int is not Long val l: Long = i.toLong() // explicit conversion required ``` This is a key Kotlin design choice (unlike Java's implicit widening) — it avoids silent precision/overflow surprises. Conversion functions: `toLong()`, `toInt()`, `toDouble()`, `toShort()`, `toByte()`, etc. ## Floating-point literals ```kotlin val x = 1.0 // Double (default) val y = 1.0f // Float via f/F suffix val z: Float = 1.0f ``` An undecorated decimal literal is **`Double`**, never `Float`. ## Literal conveniences ```kotlin val big = 1_000_000 // underscores for readability (no type change) val hex = 0xFF // Int 255 val bin = 0b1011 // Int 11 val u = 42u // UInt (unsigned) val ul = 42uL // ULong ``` ## Why interviewers ask It tests whether you understand that inference picks a concrete default type and that Kotlin's lack of implicit widening forces explicit `.toLong()`/annotations — a frequent source of beginner compile errors when interacting with `Long`-typed Java APIs or DB ids.
- What's the inferred type of `3_000_000_000`?`Long` — it exceeds `Int`'s range, so the compiler promotes the literal to `Long`. The underscores are just readability.
- Why won't `val l: Long = anInt` compile?Kotlin has no implicit numeric widening; you must call `anInt.toLong()` explicitly.
- What does `42u` infer to?`UInt` — the `u` suffix selects the unsigned integer types.
saying these in an interview costs you the question
- Thinking `val x = 1` could be `Long`
- Expecting implicit Int→Long widening like Java
- Confusing `1.0` (Double) with Float
- Not knowing the `L`/`f`/`u` suffixes
- Believing the `L` suffix changes the runtime value