问题描述
Joshua Bloch 在Effective Java"中说
Joshua Bloch in "Effective Java" said that
使用检查异常可恢复的条件和运行时间编程错误的例外(第 2 版第 58 项)
让我们看看我是否理解正确.
Let's see if I understand this correctly.
以下是我对已检查异常的理解:
Here is my understanding of a checked exception:
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 是未经检查的异常吗?
以下是我对未检查异常的理解:
Here is my understanding of an unchecked exception:
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.现在,上面的代码不能也是一个检查异常吗?我可以试着恢复这样的情况吗?我可以吗?(注意:我的第三个问题在上面的 catch
中)
4. Now, couldn't the above code also be a checked exception? I can try to recover the situation like this? Can I? (Note: my 3rd question is inside the catch
above)
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{
}
为什么他们让异常冒泡?不是越早处理错误越好吗?为什么要冒泡?
Why do they let the exception bubble up? Isn't handling the error sooner better? Why bubble up?
6.我应该冒泡确切的异常还是使用异常来掩盖它?
以下是我的阅读
在Java中,什么时候应该创建已检查异常,什么时候应该是运行时异常?
推荐答案
许多人说,根本不应该使用已检查的异常(即您应该明确捕获或重新抛出的异常).例如,它们在 C# 中被淘汰,大多数语言都没有它们.所以你总是可以抛出 RuntimeException
的子类(未经检查的异常)
Many people say that checked exceptions (i.e. these that you should explicitly catch or rethrow) should not be used at all. They were eliminated in C# for example, and most languages don't have them. So you can always throw a subclass of RuntimeException
(unchecked exception)
但是,我认为检查异常很有用 - 当您想强制 API 用户考虑如何处理异常情况(如果它是可恢复的)时,可以使用它们.只是Java平台过度使用了检查异常,让人讨厌.
However, I think checked exceptions are useful - they are used when you want to force the user of your API to think how to handle the exceptional situation (if it is recoverable). It's just that checked exceptions are overused in the Java platform, which makes people hate them.
至于具体问题:
NumberFormatException
是否考虑检查异常?
否.NumberFormatException
未选中(= 是RuntimeException
的子类).为什么?我不知道.(但应该有一个方法isValidInteger(..)
)
Is the
NumberFormatException
consider a checked exception?
No.NumberFormatException
is unchecked (= is subclass ofRuntimeException
). Why? I don't know. (but there should have been a methodisValidInteger(..)
)
RuntimeException
是未经检查的异常吗?
是的,没错.
Is RuntimeException
an unchecked exception?
Yes, exactly.
我应该在这里做什么?
这取决于此代码的位置以及您想要发生的事情.如果它在 UI 层 - 抓住它并显示警告;如果它在服务层 - 根本不要抓住它 - 让它冒泡.只是不要吞下异常.如果在大多数情况下发生异常,您应该选择以下之一:
What should I do here?
It depends on where this code is and what you want to happen. If it is in the UI layer - catch it and show a warning; if it's in the service layer - don't catch it at all - let it bubble. Just don't swallow the exception. If an exception occurs in most of the cases you should choose one of these:
- 记录并返回
- 重新抛出它(声明它被方法抛出)
- 通过在构造函数中传递当前异常来构造一个新异常
现在,上面的代码不能也是一个检查异常吗?我可以试着恢复这样的情况吗?我可以吗?
本来可以.但是也没有什么能阻止您捕获未经检查的异常
Now, couldn't the above code also be a checked exception? I can try to recover the situation like this? Can I?
It could've been. But nothing stops you from catching the unchecked exception as well
为什么人们要在 throws 子句中添加类 Exception
?
最常见的原因是人们懒得考虑捕捉什么和重新扔掉什么.抛出 Exception
是一种不好的做法,应该避免.
Why do people add class Exception
in the throws clause?
Most often because people are lazy to consider what to catch and what to rethrow. Throwing Exception
is a bad practice and should be avoided.
唉,没有单一的规则可以让您确定何时捕获、何时重新抛出、何时使用已检查的异常以及何时使用未检查的异常.我同意这会导致很多混乱和很多糟糕的代码.Bloch 陈述了一般原则(您引用了其中的一部分).并且一般的原则是向可以处理的层重新抛出异常.
Alas, there is no single rule to let you determine when to catch, when to rethrow, when to use checked and when to use unchecked exceptions. I agree this causes much confusion and a lot of bad code. The general principle is stated by Bloch (you quoted a part of it). And the general principle is to rethrow an exception to the layer where you can handle it.
这篇关于了解 Java 中已检查与未检查的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!