En Kotlin, el modificador const val se utiliza solo para constantes en tiempo de compilación a nivel de archivo (top-level) o dentro de objetos (object) y objetos compañero. Las propiedades declaradas como val dentro de las clases se convierten en propiedades finales normales sin inicialización estática. Una característica importante: const val no puede heredarse, mientras que val se puede sobreescribir (si está permitido).
Las constantes (const val) no pueden ser abstractas, ya que deben tener un valor en el momento de la compilación. Las val normales permiten implementar el patrón de constantes en jerarquías mediante propiedades abiertas, sin embargo, en tiempo de ejecución se accede a través de un getter, lo cual es diferente de la compilación en Java.
open class Base { open val info: String = "base" } class Child : Base() { override val info = "child" } object Constants { const val APPLICATION_NAME = "MyApp" }
¿Se puede declarar
const valen una interfaz o clase abstracta y luego sobrescribir/heredar?
No. En Kotlin no se puede declarar const val dentro de una interfaz o clase abstracta; esto solo está permitido a nivel de objeto (object) y top-level. No hay variables estáticas finales análogas disponibles para la herencia.
interface Foo { // const val X = "constant" // error de compilación: 'val' constante solo se permite en top-level, en objetos o en objetos compañeros }
Historia
El equipo intentó reutilizar constantes de cadena a través de la herencia de interfaces en varios módulos de Android, declarando las como
const val- recibieron un error de compilación y se vieron obligados a mover las constantes a top-level, lo que deterioró la encapsulación.
Historia
En el proyecto, trasladaron todos los campos estáticos finales de Java a campos
valen clases abiertas, esperando un comportamiento similar (const en tiempo de compilación), pero se convirtieron en propiedades normales con un getter. Como resultado, aumentó el tiempo de acceso, lo que afectó negativamente a los caminos calientes (hot path) de la aplicación de microservicios.
Historia
Al portar clases Java de contenedores de constantes a Kotlin, los desarrolladores hicieron constantes dentro del objeto compañero, pero se encontraron con problemas de acceso desde el código Java: las constantes eran visibles como campos del propio compañero, no de la clase, lo que causó confusión en la API y errores adicionales de interoperabilidad.