让我们说我们有以下条件。
A)
public void method() throws ... {
XXXXXXXXXXXXXXXXXXXXXXX;
}
或
B)
public void method(){
try{
XXXXXXXXXXXXXXXXXXXXXXX;
}catch(...){
//doing something here
}
}
假设标有"XXXX"
的行是可能引发异常的一行代码(假设此行不会引发错误)。
所以我的问题是,我应该在第一种情况下(在方法声明中)提到的例外情况以及我应该在我的catch块中捕获的异常?
*我知道只是抛出和捕获异常异常就足够了,但我认为这不是一个好的设计。 *
答案 0 :(得分:3)
看起来您似乎在问如何判断给定方法将会或可能抛出的异常。由于您并没有告诉我们您尝试运行哪种方法,因此很难回答。但Java的一部分原因是它是静态类型的,事实上你确实知道任何方法都可以抛出哪些异常。这是一个编译时错误,不能明确地捕获您调用的任何异常方法,因此如果您应该捕获某些内容,您将立即知道。例外情况是RuntimeException
和它的子节点,它们故意不属于编译时合同。
通常情况下,RuntimeException
不应被捕获,它们表示某种状态,您不应该让您的程序首先进入(例如不检查null
}触发NullPointerException
)但您可以查看文档以了解您正在使用的方法,以查看它们可能会抛出的内容。例如,String.substring()
表示它可能会抛出IndexOutOfBoundsException
。通常,您应该提前进行必要的索引检查,但如果您不能提前做到,那么您可以抓住它,如下所示:
int userInputWeCantTrust = -4;
try {
System.out.println("foo".substring(userInputWeCantTrust));
} catch (IndexOutOfBoundsException e) {
System.err.println("Looks like I can't trust you, user.");
}
执行此操作时,您希望尽可能明确地使用异常类型(例如,捕获IndexOutOfBoundsException
,而不是RuntimeException
),并在{{1}中放置尽可能少的代码阻止。否则,您可能会意外捕获应该允许继续传播的异常。
决定抓或扔是一个设计决定。如果你能够处理一个给定的异常,那么你将它包装在try-catch中,如果你不是,你就不会。
示例一,解析整数,失败时默认为try
:
default
示例二,解析用户输入,让main方法处理错误报告:
public static int parse(String s, int default) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
return default;
}
}
这实际上取决于您的使用案例。
答案 1 :(得分:1)
编译器将为您解答这些问题:您需要捕获代码可以生成的Exceptions
,或将它们声明为您的方法抛出。如果你遗漏了任何内容,编译器会抱怨。 RuntimeExceptions
是例外。
您唯一的选择是捕获这些特定异常或使用throws
传播它们。这个选择 - Exceptions
被抛出,被抓住了,取决于你的特定目标。
您需要熟悉您正在使用的API,并且API方法会抛出API的一部分Exceptions
,但如果您错过了一个,那么您的代码将无法编译,你有机会解决它。
答案 2 :(得分:0)
简要说一下:
如果您没有按照become part of the documentation for that method(例如JavaDocs)处理异常,那么将异常标记为抛出是好的:
方法可以抛出的任何异常都是方法的一部分 公共编程接口。那些称之为方法的人必须知道 方法可以抛出的异常,以便他们可以决定要做什么 做他们。这些例外同样是该方法的一部分 编程接口作为参数和返回值。
对于catch
块,主要是确保您正在处理正在捕获的任何异常(至少记录异常消息)。您可能希望尝试从异常中恢复,抛出不同类型的异常或只记录输出:
E.g。好:
catch(NullPointerException e) {
variable = "default-value";
}
catch(NullPointerException e) {
throw new OhNoesException();
}
catch(NullPointerException e) {
log.warn(e.getMessage());
}
如果您正在做的只是放弃Exception,那么抛出它会更好。 E,g,Bad(作为一般经验法则):
catch(NullPointerException e) {}
答案 3 :(得分:0)
尝试考虑调用者对您的方法的期望。想想这是你的方法给调用者的“承诺”。
现在,假设您正在调用某些内容,并且您可能会遇到异常。你可能会问自己的问题是:我是否仍能履行我通过处理该异常而做出的承诺,并继续下去?如果你不能:抛出异常(或者,抛出一个不同的异常 - 通过将它包装在MyApplicationException或其他东西中)。
如前所述:这可能是一个设计问题 - 整数解析方法的“承诺”可能是“以最佳方式将字符串转换为数字”,在这种情况下,您不会在任何情况下抛出异常,或者它可以“解析一个应该是整数的正确编码的字符串”;在这种情况下抛出异常将是一个更好的主意。