En Kotlin se introdujo el concepto de clases inline/clases de valor (ahora llamadas clases de valor) para minimizar el overhead de tiempo de ejecución al trabajar con envoltorios sobre tipos primitivos y estructuras pequeñas. La idea se toma de otros lenguajes (por ejemplo, estructuras en C#), donde tal optimización es útil para mejorar el rendimiento sin perder la tipificación.
Crear clases envoltorio (por ejemplo, para tipos de entidad o identificadores) sin optimización conduce a la presencia de un objeto adicional en memoria, lo que afecta el rendimiento, la recolección de basura y puede llevar a un overhead de Boxing/Unboxing. A menudo surge el deseo de tener una tipificación estricta (por ejemplo, UserId en lugar de Int), pero sin la creación real de objetos.
La clase de valor se declara con el modificador value. En la mayoría de las situaciones, la JVM no crea un objeto adicional: la clase de valor se reemplaza directamente por su campo (inlining). Esto proporciona seguridad de tipo y un rendimiento cercano a "simplemente Int".
Ejemplo de código:
@JvmInline value class UserId(val value: Int) fun showId(id: UserId) = println(id.value) val id = UserId(15) showId(id) // Sin crear un objeto separado UserId
Características clave:
¿Pueden las clases de valor tener múltiples propiedades?
No, la clase de valor solo puede contener una propiedad.
// Error: // value class Money(val amount: Int, val currency: String)
¿Se puede crear una clase de valor con una propiedad nullable?
El campo value de la clase de valor no puede ser nullable: solo tipos no nulos.
// Error: // value class Name(val value: String?)
¿Se puede usar herencia con clases de valor?
La clase de valor no admite herencia y no puede ser abstracta o sellada.
// Error: // value class NewId(val value: Int): BaseId()
Un desarrollador creó una clase de valor para una entidad con dos propiedades (por ejemplo, un par de Int y String) y obtuvo un error de compilación.
Pros:
Un desarrollador utiliza clase de valor para un tipo identificador con un solo campo (por ejemplo, UserId), lo que funciona rápida y seguramente.
Pros: