ProgramaciónDesarrollador Backend

¿Qué es un companion object en Kotlin, cuáles son sus características y limitaciones? ¿Cómo usar companion objects para crear métodos de fábrica y estado estático?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

El companion object (companion object) en Kotlin es un objeto declarado dentro de una clase con la palabra clave companion, que permite agrupar métodos y propiedades estáticas, similar a los miembros estáticos en Java. A diferencia de los static en Java, en Kotlin cada companion object es un objeto completo, y a nivel de bytecode, las referencias a sus miembros se compilan como estáticas.

Principales características y limitaciones:

  • Nombre por defecto — si no se especifica explícitamente, el objeto se llama Companion.
  • El companion object puede implementar cualquier interfaz, lo que lo hace conveniente, por ejemplo, para crear métodos de fábrica.
  • Dentro del companion object, hay acceso a los miembros privados de la clase exterior.
  • Cada clase puede tener solo un companion object.
  • Se puede acceder a los miembros del companion object como si fueran estáticos a través del nombre de la clase, o como miembros del objeto.

Ejemplo:

class MyFactory private constructor(val value: Int) { companion object { fun create(x: Int): MyFactory = MyFactory(x) } } val instance = MyFactory.create(10)

Pregunta capciosa.

¿Por qué no se recomienda guardar estado (por ejemplo, variables mutables) dentro de un companion object en aplicaciones multihilo?

Respuesta con ejemplo:

Si se coloca estado mutable dentro de un companion object, se convierte en compartido entre todas las instancias de la clase y hilos, lo que lleva a condiciones de carrera sin sincronización adicional.

class Counter { companion object { var count = 0 fun increment() { count++ } } } Counter.increment() // condición de carrera en llamadas simultáneas

Ejemplos de errores reales debido al desconocimiento de las sutilezas del tema.


Historia

En un proyecto de Android, los desarrolladores colocaron la configuración del entorno dentro de un companion object para gestionar un interruptor de depuración. Esto llevó a confusiones cuando diferentes fragmentos cambiaron el mismo valor global, y se produjeron comportamientos inesperados durante transiciones asíncronas.


Historia

En el backend, parte de la funcionalidad se trasladó a un companion object junto con un caché mutable. Bajo alta carga, se produjeron errores y un estado de datos inconsistente debido a la falta de sincronización.


Historia

Un desarrollador principiante intentó implementar una interfaz solo en el companion object, pensando que podría usar la clase como esa interfaz. Como resultado, se encontró con la imposibilidad de pasar la clase en lugar del companion object, ya que el companion es el único objeto asociado con la clase, y no la clase misma.