我已经创建了一个帮助程序,该帮助程序在另一个函数中使用 Exception 参数返回错误消息。(这是一个示例)
void func(int n){
try {
// this will throw ArithmeticException if n is 0
int x = 10 / n;
int y[] = new int[n];
y[x] = 10;
// this will throw ArrayIndexOutOfBoundsException
// if the value of x surpasses
// the highest index of this array
System.out.println("No exception arose");
}
catch (Exception e) {
System.out.println(getErrorType(e));
}
}
String getErrorType(Exception e){
String errorMessage = "";
if (e instanceof ArithmeticException)
errorMessage = "ArithmeticException, Can't divide by 0";
if (e instanceof ArrayIndexOutOfBoundsException)
errorMessage = "ArrayIndexOutOfBoundsException, This index doesn't exist in this array";
else
errorMessage = "error";
return errorMessage;
}
如您所见,我正在使用 instanceof 来获取Exception类型,并且我还可以向String函数添加更多信息,例如错误消息。另外,我可以在此帮助程序中包含许多错误类型。 我的问题是,
我已经知道在try catch块中很好的用途是使用特定的Exceptions来添加具有特定Exception的catch级别。但是我想使其通用化。
答案 0 :(得分:0)
通常,您希望在try / catch子句中指定期望发生的异常,这样,当其他人浏览您的代码时,他们将知道如果他们需要处理它们,将会想到哪些异常。
实际上,您也可以通过以下操作将catch子句组合为一个子句:
try {
// this will throw ArithmeticException if n is 0
int x = 10 / n;
int y[] = new int[n];
y[x] = 10;
// this will throw ArrayIndexOutOfBoundsException
// if the value of x surpasses
// the highest index of this array
System.out.println("No exception arose");
}
catch (ArithmeticException | ArrayIndexOutOfBoundsException | SomeOtherException e) {
e.printStackTrace();
}
答案 1 :(得分:0)
似乎有很多额外的工作,而且我看不到将所有异常处理代码放在大型函数中的好处。 Java的最佳实践是始终保持代码模块化,并尽可能地利用该语言。
如果只是您想要的详细信息,则使用自定义消息重新抛出异常会更巧妙。这是一个简单的示例:
int divide (int a, int b) {
try {
return a / b;
} catch (ArithmeticException e) {
throw new ArithmeticException("Divide by 0", e);
}
}
请记住,您要以不同的方式处理异常,因为您不希望您的应用程序因可修复的小事情而终止-这不是一个好的设计。如果您的应用遇到了可以从中恢复的问题,例如来自用户的错误输入,则可以捕获异常并停止崩溃。使用通用异常将阻止您执行此操作,因为您将不知道引发了什么异常。您可以在getErrorType
函数中进行处理,但最终可能会遇到类似这样的情况:
String getErrorType(Exception e){
String errorMessage = "";
if (e instanceof ArithmeticException)
errorMessage = "ArithmeticException, Can't divide by 0";
warnUserToChangeValue();
if (e instanceof IllegalArgumentException)
errorMessage = "Bad Argument";
warnUserToChangeValue();
if (e instanceof ArrayIndexOutOfBoundsException)
errorMessage = "ArrayIndexOutOfBoundsException, This index doesn't exist in this array";
else
errorMessage = "error";
return errorMessage;
}
这真的很难看。我建议保持简单,并根据需要进行捕获:
catch (ArithmeticException e | IllegalArgumentException e)
{
// The user probably entered a bad value, no reason to terminate, just tell them
warnUserToChangeValue();
}
答案 2 :(得分:0)
捕获 Exception 通常是一个不好的做法,因为它还会吞噬无关的错误,例如NullPointerException,IllegalStateException,IllegalArgumentException和其他运行时异常,这些错误都是BUGS,实际上应该继续传播。
因此使用:
FF, FE
捕获IllegalArgumentException确实是一种糟糕的做法,除了在错误处理的最顶层。在这种情况下,您所能做的就是将其报告到某个地方(例如日志)。
这是一个错误。
该规则的一个例外是,当您拥有诸如Thread之类的东西时,因为它非常关键,因此永不中断。
在这种情况下,捕获Throwable更为有效。
答案 3 :(得分:0)
TL; DR
丢弃整个try / catch块,并使用最顶层的方法告诉用户您无法执行他命令您执行的任务。
概念
看起来您对如何处理特殊情况有着(广泛的)误解,即“异常很糟糕!我必须尽早发现它们!”错了异常可以完美地告诉呼叫者我的失败:“我无法完成工作。您可以决定是否可以不这样做,以其他方式重试,或者只是向呼叫者发送信号”。
您的func()
有一些工作要做(无论“合同”可能是什么)。从方法中抛出异常是为了表明该方法未完全完成其工作。
在您的情况下,func()
调用者没有机会发现该方法无法执行任何操作(因此很可能无法履行其合同)。因此,您的呼叫者会开心地继续前进,而不知道他的算法的关键步骤失败了,从而产生跟进错误,甚至更糟:数据废话。
因此,不捕获异常绝对是更好的选择,异常会波及到您的呼叫者,这样他就可以知道失败的原因,并可以决定是否即使在func()
失败之后也可以明智地继续。
在大多数情况下,该决定显示为“如果我的算法中的任何事情失败,整个事情失败了,我立即想中止其所有计算”。如果您什么都没抓住,那就是免费从异常中获取的东西。
您的捕获条款
与Java Runtime与该异常关联的自动文本格式相比,您尝试呈现一种用户友好的消息来更好地描述问题。
乍一看,这似乎是合理的,但是...
如果此func()
是代码深处使用的帮助程序,那么坐在机器前的最终用户将发现您的措辞比Java文本更有帮助。仅当您实现了一个桌面计算器,其中用户明确希望将两个数相除时,有关零除的错误文本对用户才有帮助。在典型情况下,他无法将零除与他希望从您的程序中得到的任何内容(例如,信用利息计算)相关联。
回答您的问题