estoy estudiando kotlin Tengo una pregunta sobre el uso de la excepción. ¿Cuál es mejor usar la excepción de objeto o la excepción de clase en kotlin?
object CustomDuplicateId : RuntimeException("Invalid user with Id") class CustomDuplicateId : RuntimeException("Invalid user with Id") si estoy usando esta excepción solo en una ubicación, stacktrace siempre es el mismo. así que creo... que no necesita usar class . ¿Es correcto?
¿O es malo usar la excepción singleton?
¿Alguien puede decirme qué es mejor código para escribir una excepción?
Hay varias razones por las que es incorrecto usar object .
el stacktrace es incorrecto de varias maneras:
<clinit> como la primera línea en el seguimiento de la pila porque se crea al inicializar la clase del objeto por primera vez.técnicamente, la clase de excepción tiene partes mutables y sería peligroso/incorrecto permitir que el código del usuario altere esto. Un ejemplo muy concreto de esto es que el código de usuario podría agregar excepciones suprimidas a su instancia de excepción (que solo sería válida para un lanzamiento y, sin embargo, persistiría en su objeto). Esto es técnicamente una pérdida de memoria.
es probable que necesite mensajes diferentes con más información sobre por qué se lanzó (en ese caso, la ID duplicada es muy necesaria), por lo que necesita diferentes instancias con datos diferentes de todos modos
podría lanzarlo desde diferentes lugares en el futuro (¿incluso ahora en pruebas/simulacros tal vez?), y en ese caso el stacktrace sería aún más incorrecto
independientemente de tecnicismos como los anteriores, la class contra el object también envía un mensaje al lector que no está claro: ¿por qué un object aquí? Esta excepción no es inherentemente única. Da la casualidad de que lo lanzas en un lugar específico en este momento y confías en que el stacktrace sea el mismo.
Aquí hay un ejemplo para el problema principal (# 1):
object MyExceptionObject : RuntimeException("boom") fun main() { try { caller1() // line 7 } catch (e: Exception) { } caller2() // line 10 } fun caller1() = doStuff() // line 13 fun caller2() = doStuff() // line 14 fun doStuff() { throw MyExceptionObject // line 17 } El caller1() lanza la excepción pero esa es atrapada. El caller2() vuelve a lanzar la excepción y esa no se detecta. El seguimiento de pila que obtenemos para la excepción no detectada muestra incorrectamente la persona que llama 1 (con las líneas 7 y 13), pero la correcta debería ser la persona que llama 2 (con las líneas 10 y 14):
Exception in thread "main" com.example.MyExceptionObject: boom at com.example.MyExceptionObject.<clinit>(ExceptionObjectExample.kt) at com.example.ExceptionObjectExampleKt.doStuff(ExceptionObjectExample.kt:17) at com.example.ExceptionObjectExampleKt.caller1(ExceptionObjectExample.kt:13) at com.example.ExceptionObjectExampleKt.main(ExceptionObjectExample.kt:7) at com.example.ExceptionObjectExampleKt.main(ExceptionObjectExample.kt)Con todo, solo usa una clase.