Kotlin amplía el concepto clásico de singleton a través de la palabra clave object. Con ello se implementan los siguientes patrones:
object Logger { ... }).Ejemplo de objeto singleton:
object DatabaseManager { fun connect() { /*...*/ } } DatabaseManager.connect()
Expresión de objeto:
val listener = object : MouseAdapter() { override fun mouseClicked(e: MouseEvent) { /*...*/ } }
Objeto compañero:
class User { companion object Factory { fun create(name: String) = User() } } val user = User.create("Ivan")
Matices:
¿Cuál es la diferencia entre companion object y object declaration? ¿Son accesibles sus miembros como estáticos?
Respuesta:
object declaration — singleton global, miembro de clase, interfaz o nivel externo.companion object — un tipo especial de object declaration dentro de una clase, cuyos miembros se pueden llamar como si fueran estáticos (a través del nombre de la clase). Sin embargo, a diferencia de Java, son en realidad campos del objeto singleton.Ejemplo de la diferencia:
class A { companion object { fun foo() {} } object NestedObj { fun bar() {} } } A.foo() // OK A.NestedObj.bar() // OK, pero no es un método estático
Historia
Un desarrollador definió un estado mutable dentro de una declaración de objeto y comenzó a usarlo desde diferentes hilos sin sincronización, sin darse cuenta de que los objetos singleton se comparten en toda la aplicación y pueden causar condiciones de carrera.
Historia
Al declarar un objeto en lugar de un companion object dentro de una clase, se requería el uso de métodos estáticos, pero tuvieron que ser llamados a través de la instancia, lo que deterioró la legibilidad y provocó errores al migrar desde Java.
Historia
En el código de UI, el programador creaba un nuevo objeto cada vez a través de la expresión de objeto para el controlador de eventos. Erróneamente pensaba que era un singleton y que el estado se mantendría; como resultado, surgieron fugas de memoria debido al manejo incorrecto del ciclo de vida.