约书亚·布洛赫在《有效的Java》中说过
为以下情况使用检查异常
可恢复条件和运行时
编程错误的例外
(第二版第58项)
看看我理解的对不对。
以下是我对受控异常的理解:
try{
String userInput = //read in user input
Long id = Long.parseLong(userInput);
}catch(NumberFormatException e){
id = 0; //recover the situation by setting the id to 0
}
1. 上述异常是否被认为是受控异常?
2. RuntimeException是未检查的异常吗?
以下是我对未检查异常的理解:
try{
File file = new File("my/file/path");
FileInputStream fis = new FileInputStream(file);
}catch(FileNotFoundException e){
//3. What should I do here?
//Should I "throw new FileNotFoundException("File not found");"?
//Should I log?
//Or should I System.exit(0);?
}
4. 现在,上面的代码不能也是一个受控异常吗?我可以试着挽回这样的局面吗?我可以吗?(注:我的第三个问题在上面的陷阱里)
try{
String filePath = //read in from user input file path
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
}catch(FileNotFoundException e){
//Kindly prompt the user an error message
//Somehow ask the user to re-enter the file path.
}
5. 人们为什么要这样做?
public void someMethod throws Exception{
}
为什么他们让异常冒出来?早点处理错误不是更好吗?为什么要冒出来?
6. 我是否应该冒泡出确切的异常或使用异常掩盖它?
以下是我的阅读资料
在Java中,什么时候应该创建检查异常,什么时候应该是运行时异常?
何时选择已检查异常和未检查异常
1 . 如果你不确定一个异常,检查API:
java . lang . object
由java.lang.Throwable扩展
由java.lang.Exception扩展
//<-NumberFormatException是一个RuntimeException
由java.lang.IllegalArgumentException扩展
由java.lang.NumberFormatException扩展
2。是的,以及所有扩展它的异常。
3.不需要捕获和抛出相同的异常。在这种情况下,您可以显示一个新的文件对话框。
4所示。FileNotFoundException已经是一个检查异常。
5。如果期望调用someMethod的方法捕获异常,则可以抛出后者。它只是“传球”。使用它的一个例子是,如果你想在你自己的私有方法中抛出它,而在你的公共方法中处理异常。
一个很好的阅读是Oracle文档本身:http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html
Why did the designers decide to force a method to specify all uncaught checked exceptions that can be thrown within its scope? Any Exception that can be thrown by a method is part of the method's public programming interface. Those who call a method must know about the exceptions that a method can throw so that they can decide what to do about them. These exceptions are as much a part of that method's programming interface as its parameters and return value.
The next question might be: "If it's so good to document a method's API, including the exceptions it can throw, why not specify runtime exceptions too?" Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way. Such problems include arithmetic exceptions, such as dividing by zero; pointer exceptions, such as trying to access an object through a null reference; and indexing exceptions, such as attempting to access an array element through an index that is too large or too small.
在Java语言规范中还有一些重要的信息:
在throws子句中命名的受控异常类是方法或构造函数的实现者和用户之间契约的一部分。
IMHO的底线是,您可以捕获任何RuntimeException,但不需要这样做,事实上,实现不需要维护抛出的相同的未检查异常,因为这些异常不是契约的一部分。
1)不,NumberFormatException是一个未检查的异常。即使你发现了它(你不需要),因为它是未检查的。这是因为它是IllegalArgumentException的子类,而IllegalArgumentException是RuntimeException的子类。
2) RuntimeException是所有未检查异常的根。RuntimeException的每个子类都未选中。所有其他异常和Throwable都被检查,除了错误(属于Throwable)。
3/4)你可以提醒用户他们选择了一个不存在的文件,并要求一个新的文件。或者停止通知用户他们输入了无效的内容。
5)抛出并捕获“异常”是不好的做法。但更一般地,您可能会抛出其他异常,以便调用者可以决定如何处理它。例如,如果您编写了一个库来处理读取一些文件输入,而您的方法被传递给一个不存在的文件,您不知道如何处理它。打电话的人是想再问一次还是想退出?因此,您将异常沿链向上抛出给调用者。
在许多情况下,出现未检查的异常是因为程序员没有验证输入(例如您的第一个问题中的NumberFormatException)。这就是为什么捕获它们是可选的,因为有更优雅的方法来避免生成这些异常。