似乎您在问如何判断给定方法将或可能抛出哪些异常。这很难回答,因为您没有告诉我们您要运行什么方法。但是 Java 的部分要点在于它是静态类型的,而且您实际上确实知道任何方法都可以抛出哪些异常。不显式捕获您调用的任何异常方法可能会触发是编译时错误,因此您会立即知道是否应该捕获某些东西。例外情况是RuntimeException
它的孩子,它故意不属于编译时合同的一部分。
通常,RuntimeException
s 不应该被捕获,它们表示您不应该让程序首先进入的某种状态(例如不检查null
触发 a 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.");
}
当您这样做时,您希望尽可能明确地使用异常类型(例如 catch IndexOutOfBoundsException
, not RuntimeException
),并在块中放置尽可能少的代码try
。否则,您可能会意外捕获本应允许继续传播的异常。
决定接住还是扔掉是一个设计决策。如果您能够处理给定的异常,则将其包装在 try-catch 中,如果不能,则不要。
示例一,解析整数,默认为default
on failure:
public static int parse(String s, int default) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
return default;
}
}
示例二,解析用户输入,让main方法处理报错:
// the throws note here isn't actually necessary, since NFE is a RuntimeException
public static int parse(String s) throws NumberFormatException {
return Integer.parseInt(s);
}
public static void main(String[] args) {
try {
for(String s : args){
System.out.println(parse(s));
}
} catch (NumberFormatException e) {
System.err.println("You entered an invalid number.");
}
}
这实际上取决于您的用例。