我在学习Kotlin .
object CustomDuplicateId : RuntimeException("Invalid user with Id")
class CustomDuplicateId : RuntimeException("Invalid user with Id")
如果我只在一个位置使用这个异常,那么stacktrace总是相同的.
还是使用单例异常不好?
有人能告诉我写异常的更好的代码吗?
我在学习Kotlin .
object CustomDuplicateId : RuntimeException("Invalid user with Id")
class CustomDuplicateId : RuntimeException("Invalid user with Id")
如果我只在一个位置使用这个异常,那么stacktrace总是相同的.
还是使用单例异常不好?
有人能告诉我写异常的更好的代码吗?
使用object
是不正确的原因有很多.
stacktrace在几个方面都是错误的:
<clinit>
作为第一行,因为它是在首次初始化对象的类时创建的从技术上讲,exception类有可变的部分,允许用户代码对其进行篡改是危险的/不正确的.一个非常具体的例子是,用户代码可以向您的异常实例中添加suppressed exceptions个异常实例(该异常实例只对一次抛出有效,但仍会保留在您的对象中).严格来说,这是内存泄漏.
您可能需要不同的消息,其中包含有关抛出原因的更多信息(在这种情况下,非常需要重复的ID),因此您仍然需要具有不同数据的不同实例
将来你可能会从不同的地方扔掉它(即使是现在在测试/模拟中可能也是如此?),如果是那样的话,stacktrace就更加错误了
与上述技术细节无关,class
vs object
也向读者发送了一条有点不清楚的信息——为什么这里是object
?这一例外并非天生独特.碰巧你现在把它扔到一个特定的地方,并且依赖于stacktrace是相同的.
以下是主要问题(#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
}
caller1()
抛出异常,但该异常被捕获.caller2()
再次抛出异常,但该异常未被捕获.我们为未捕获异常获取的stacktrace错误地显示了调用者1(第7行和第13行),但正确的应该是调用者2(第10行和第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)
总之,只需使用一个类.