想象一下以下代码作为某个程序(java)的一部分:
function z(){
try{
//some code here, that might throw exceptions.
}catch (SomeException | SomeOtherException e){
//some exception handling here.
}
function y(){
z();
}
function x(){
y();
}
并且假设如果在函数z中抛出异常SomeException或SomeOtherException,则函数x和y不会按预期执行。 我们想编写代码,使函数x和y知道函数z中抛出了异常,并使它们相应地起作用。 什么是最好的方法呢?
function z() thrown FunctionZFailedException{
try{
//some code here, that might throw exceptions.
}catch (SomeException | SomeOtherException e){
throw new FunctionZFailedException();
}
}
function y() throws FunctionYFailedException{
try{
z();
}catch (FunctionZFailedException e){
throw new FunctionYFailedException();
}
}
function x(){
try{
y();
}catch (FunctionYFailedException e){
//Do something, like alerting user that something went wrong.
}
}
这是否太过分了,即宣布新例外的唯一目的是"转发"更高级别的其他例外?
我认为我们也可以让SomeException和SomeOtherException飞起来并在函数x中捕获它们。但imo可能会弥补不太可读的代码,
例如,如果函数z中捕获的异常是SQLException和NoSuchAlgorithmException,则函数y是login()函数。然后函数x将尝试调用login(),并捕获一个SQLException | NoSuchAlgorithmException,如果让那些异常简单地飞到最高级别,或者捕获LoginFailedException,如果我们立即捕获每个异常,并让它们抛出新的异常。看起来像捕获LoginFailedException会使代码更易读。
Imo两种方式都有它们的缺点(代码不太可读而不是引入许多异常),我想知道类似的情况通常由经验丰富的java程序员处理。关于例外的任何一般想法也赞赏感谢你们
答案 0 :(得分:1)
当您查看代码(以及方法和异常的名称)时,请查明方法及其抛出的异常是否在同一个抽象级别上。
如果你有一个getInputStream()方法,那么相应的异常就是IOException。如果在getDatabaseConnection()中调用该方法,则应捕获IOException并抛出SQLException。如果你的saveCustomerToDatabase()方法需要这个方法,那么你应该抛出类似ProcessFailedException的东西。
我不是写javadocs的忠实粉丝,但有时候你应该问问自己:我是否能够为这种方法编写好的javadoc及其在同一种语言中的异常(即技术语言,商业语言等) 。)?如果它抛出IOException,您将无法为saveCustomerToDatabase()-Method编写javadoc。
答案 1 :(得分:0)
如果您对方法z()
的当前设计感到满意,并且您希望方法y()
和x()
到"知道"在z()
发生了一些不好的事情,那么你可以在吞下它之后让z()
重新抛出异常。
public void z() {
try {
// some code here, that might throw exceptions.
} catch (SomeException | SomeOtherException e) {
// handle the exception and then rethrow it
logger.log("An exception happened in z().");
throw e;
}
}
public void y() {
try {
z();
} catch(Exception e) {
// handle problem with z() and rethrow the exception
logger.log("An exception happened when calling z().");
throw e;
}
}
public void x() {
try {
y();
} catch(Exception e) {
// handle problem with y()
logger.log("An exception happened when calling y().");
}
}