在什么时候你会创建自己的异常类而不是使用java.lang.Exception?(所有的时间?只有在包装外使用它?只有它必须包含高级逻辑?等等...)
我认为你需要问自己一个略有不同的问题"创建一个新的例外给我或开发人员使用我的代码有什么好处?" 它给你或其他人带来的唯一好处就是处理异常的能力.这似乎是一个明显的答案,但实际上并非如此.您应该只处理可以合理恢复的异常.如果您抛出的异常是一个真正致命的错误,为什么让开发人员有机会错误处理它?
更深入的讨论:自定义异常:什么时候应该创建它们?
原因一:
需要抓住具体的东西.如果调用代码需要处理特定的异常条件,则需要区分异常,并且Java区分具有不同类型的异常,因此您需要编写自己的异常.
基本上,如果有人必须写:
catch(ExistingException e) { if({condition}) { { some stuff here} } else { { different stuff here} } }
您可能想要写一个特定的扩展名; catch异常匹配比条件更清晰,恕我直言.
请记住:您的新Exception 可以是 RuntimeException的子类
原因二:
API整合.如果您编写了一个接口并且有多个实现,那么它们可能会调用不同的API,并抛出一大堆不同的非RuntimeExceptions:
interface MyInterface { void methodA(); } class MyImplA { void methodA() throws SQLException { ... } } class MyImplB { void methodA() throws IOException { ... } }
你真的想让MyInterface.methodA抛出SQLException和IOException吗?也许那么在自定义异常中包装可能的异常是有意义的.这也可以是RuntimeException.甚至RuntimeException本身......
我相信:
catch (Exception e) { ... }
......是一个应该避免的反模式.您可能需要在应用程序的某个位置使用一个集中的广泛捕获,以记录错误并防止整个应用程序终止 - 但是将它们分散在各处都是不好的.
为什么:
try { if(myShape.isHidden()) { throw new Exception(); } // More logic } catch (Exception e) { MyApp.notify("Can't munge a hidden shape"); }
所以你试试这个,由于编码错误,myShape为空.当运行时试图取消对myShape的拒绝时,会抛出NullPointerException.当应该报告空指针时,此代码报告隐藏的形状.
要么做出自己的异常,要么在API中找到适当的专门异常.它不像扩展Exception或RuntimeException是繁重的.
当我想以不同于其他人的方式对待我的例外时.如果我想抓住我的并传播其他人的,或者如果我想抓住其他人并传播我的,或者如果我想抓住两者但是以不同方式对待它们,那么我将为我的异常定义一个单独的类.如果我想对它们进行相同的处理,无论是通过传播它们还是通过捕获它们(并且使用捕获的异常以任何方式做同样的事情),我将使用标准类.
如果存在语言运行库或库的现有异常,请使用它ELSE创建自己的,并将其记录良好,并且应该在99%的情况下工作.