A boxed primitive is a Java reference representation of a value such as int. Kotlin presents Int, Boolean, and similar types uniformly, while choosing primitive or boxed JVM representations behind the scenes. section 8.1 section 8.1.1
One Kotlin type, two JVM representations
val i: Int = 1 val list: List<Int> = listOf(1, 2, 3) The standalone Int is usually compiled to Java int. The Int used as a generic type argument is compiled to java.lang.Integer, because JVM generics require reference types. section 8.1.1
Boxing becomes unavoidable when a primitive value must behave as an object. Kotlin hides the distinction in source code, but it remains relevant for Java interoperability and for the representation of generic collections. section 8.1.1 section 8.1.3
Nullability forces boxing
data class Person(val name: String, val age: Int? = null) An Int? can contain null, so Java cannot store it as primitive int; Kotlin compiles it as java.lang.Integer. Null checks must happen before comparing nullable values. section 8.1.3
Boxed representations appear in these situations:
- Nullable primitive types such as Int? and Boolean? require Java reference types. section 8.1.3
- Generic classes such as List<Int> use boxed values because the JVM does not support primitive type arguments. section 8.1.3
- Large primitive collections may require arrays or a library designed for primitive storage. section 8.1.3
Listing 8.1 Using nullable primitive types
data class Person(val name: String,
val age: Int? = null) {
fun isOlderThan(other: Person): Boolean? {
if (age == null || other.age == null)
return null
return age > other.age
}
}
fun main() {
println(Person("Sam", 35).isOlderThan(Person("Amy", 42)))
// false
println(Person("Sam", 35).isOlderThan(Person("Jane")))
// null
}
Inspect nullable Int in a data class and observe how missing values affect comparison results. section 8.1.3

