[英]How to handle an exception in Java thrown by a method into another method?
Let's suppose I have this class:假设我有这门课:
public class Obj1{
...
public void do_Something(int someParameter) throws SomeException {
if(...) throw new SomeException();
...
}
...
}
then, somewhere然后,某处
public class Obj2{
...
public void do_SomeOtherThing(Obj1 obj1){
obj1.do_Something();
//apparently the only solution is try-catching it directly, even if I'm not in the main...
...
}
I've learned that exceptions should only be thrown by METHOD, and catched by MAIN, so, my question is: is try-catch the unique way to handle sub-method exceptions, or the most external method (do_SomeOtherThing) will throw it, so that I can try-catch it directly in main, deleting the try-catch in Object2 class?我了解到异常应该只由 METHOD 抛出,并由 MAIN 捕获,所以,我的问题是:try-catch 是处理子方法异常的唯一方法,还是最外部的方法 (do_SomeOtherThing) 会抛出它,这样我就可以直接在 main 中尝试捕获它,删除 Object2 类中的 try-catch?
Basically, can I do as follows?基本上,我可以这样做吗?
public static void main(String[] args){
Object1 obj1 = new Object1();
Object2 obj2 = new Object2();
try{
obj2.do_SomeOtherThing(obj1);
}
catch(SomeException e){
...
}
}
or not?或不?
A checked exception is part of the contract that a method has with its caller, and a thrown exception will always need to be handled one way or another.已检查异常是方法与其调用者之间的契约的一部分,抛出的异常总是需要以一种或另一种方式处理。
The correct answer depends on the exact situation:正确答案取决于具体情况:
String getStringFromRemoteServer() throws IOException { ... }
String getConfigString() {
try {
return getStringFromRemoteServer();
} catch (IOException e) {
LOG.warn("Failed to contact server, using local version.", e);
return getLocalString();
}
}
In this case we have an alternative source of the data we need, so if the preferred method fails we catch the exception, log it (so that we know a problem exists with our network) and call the alternative.在这种情况下,我们有一个我们需要的数据的替代来源,所以如果首选方法失败,我们会捕获异常,记录它(以便我们知道我们的网络存在问题)并调用替代方法。
Configuration parseConfiguration(String configString) throws ParseException { ... }
void loadConfiguration() {
try {
this.globalConfig = parseConfiguration(getConfigString());
} catch (ParseException e) {
throw new RuntimeException("Corrupted config", e);
}
}
In this case an exception means that the configuration of our application is fatally broken.在这种情况下,异常意味着我们应用程序的配置被严重破坏。 There is no point in trying to handle this error, and no point in any of our callers trying to handle it, so declaring
throws
on loadConfiguration()
would just be confusing clutter.尝试处理这个错误是没有意义的,我们的任何调用者尝试处理它也是没有意义的,所以在
loadConfiguration()
上声明throws
只会造成混乱。 We wrap the exception in a RuntimeException
and rethrow it.我们将异常包装在
RuntimeException
并重新抛出它。 Note that we don't log it -- there will be some top level reporting of uncaught exceptions, so logging it here would be repetition.请注意,我们不记录它——会有一些未捕获异常的顶级报告,所以在这里记录它会重复。
It is still valuable to have parseConfiguration()
throw a checked exception, because when we are calling it from the interactive configuration editor we catch the exception and display an error message to the user.让
parseConfiguration()
抛出已检查的异常仍然很有价值,因为当我们从交互式配置编辑器调用它时,我们会捕获异常并向用户显示错误消息。
int stringToInteger(String s) throws BadNumberException { ... }
String decimalStringToHexString(String s) throws BadNumberException {
return intToHex(stringToInteger(s));
}
In this case we are not changing the meaning of the exception -- decimalStringToHexString
is converting a number from a string, and one possible outcome is that the string is illegal.在这种情况下,我们不会改变异常的含义
decimalStringToHexString
正在从字符串转换数字,一种可能的结果是该字符串是非法的。 Our caller needs to be aware of that as a possible outcome, just as callers of stringToInteger()
are, so we simply declare the exception and let our caller handle it.我们的调用者需要意识到这是一个可能的结果,就像
stringToInteger()
调用者一样,所以我们只需声明异常并让我们的调用者处理它。 Our caller knows the context they are using the number in, so they can decide how to handle the exception.我们的调用者知道他们使用号码的上下文,因此他们可以决定如何处理异常。
A couple of rules:几条规则:
try { ... } catch (Exception e) {}
the empty catch clause will make it hard to spot why your code doesn't work.try { ... } catch (Exception e) {}
空的 catch 子句将很难发现你的代码为什么不起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.