了解 Java 中的已检查与未检查异常 [英] Understanding checked vs unchecked exceptions in Java

查看:19
本文介绍了了解 Java 中的已检查与未检查异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Joshua Bloch 在Effective Java"中说过

Joshua Bloch in "Effective Java" said that

使用检查的异常可恢复的条件和运行时间编程错误的例外(第 2 版第 58 条)

Use checked exceptions for recoverable conditions and runtime exceptions for programming errors (Item 58 in 2nd edition)

让我们看看我是否理解正确.

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.

这是我对该主题的扩展观点.

至于具体问题:

  1. 是否将 NumberFormatException 视为已检查异常?
    否.未选中 NumberFormatException(= 是 RuntimeException 的子类).为什么?我不知道.(但应该有一个方法 isValidInteger(..))

  1. Is the NumberFormatException consider a checked exception?
    No. NumberFormatException is unchecked (= is subclass of RuntimeException). Why? I don't know. (but there should have been a method isValidInteger(..))

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 中的已检查与未检查异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆