Java:已检查vs未经检查的异常说明

Java:已检查vs未经检查的异常说明

我已经在StackOverFlow上阅读了有关已检查和未经检查的异常的多个帖子。老实说,我还是不太确定如何正确使用它们。

Joshua Bloch在“ Effective Java ”中说过

对可恢复条件使用已检查的异常,对编程错误使用运行时异常(第2版中的第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.现在,上述代码也不能成为检查异常吗?我可以尝试恢复这样的情况吗?我可以吗?(注意:我的第3个问题在catch上面)

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{}

他们为什么要让异常泡沫化?是不是更快地处理错误?为什么泡起来?

编辑:我应该冒泡确切的异常或使用异常掩盖它吗?

以下是我的阅读材料

在Java中,何时应该创建一个已检查的异常,何时应该是运行时异常?

何时选择已检查和未检查的例外


繁星淼淼
浏览 871回答 4
4回答

收到一只叮咚

某些东西是否是“已检查的异常”与您是否捕获它或在catch块中执行的操作无关。它是异常类的属性。凡是是的一个子类Exception ,除了对RuntimeException和它的子类是经过检查的异常。Java编译器强制您捕获已检查的异常或在方法签名中声明它们。它本来应该提高程序安全性,但大多数意见似乎是它不值得它创造的设计问题。他们为什么要让异常泡沫化?不处理错误越快越好?为什么泡起来?因为这是例外的全部要点。没有这种可能性,您不需要例外。它们使您能够在您选择的级别处理错误,而不是强迫您在最初发生的低级方法中处理它们。

慕姐4208626

以上是否被认为是一个经过检查的例外?不,你是处理异常的事实并不使它成为一个Checked Exception如果它是一个RuntimeException。是RuntimeException一个unchecked exception?是Checked Exceptions是subclasses的java.lang.Exception&nbsp;Unchecked ExceptionsARE&nbsp;subclasses的java.lang.RuntimeException抛出已检查异常的调用需要包含在try {}块中,或者在方法调用者的上一级中处理。在这种情况下,当前方法必须声明它抛出所述异常,以便调用者可以做出适当的安排来处理异常。希望这可以帮助。问:我应该冒泡确切的异常还是使用Exception掩盖它?答:是的,这是一个非常好的问题和重要的设计考虑因素。Exception类是一个非常通用的异常类,可用于包装内部低级异常。您最好创建一个自定义异常并将其包装在其中。但是,也是一个重大问题 - 永远不要掩盖潜在的原始根本原因。例如,Don't ever请执行以下操作 -try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;attemptLogin(userCredentials);}&nbsp;catch&nbsp;(SQLException&nbsp;sqle)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;LoginFailureException("Cannot&nbsp;login!!");&nbsp;//<--&nbsp;Eat&nbsp;away&nbsp;original&nbsp;root&nbsp;cause,&nbsp;thus&nbsp;obscuring&nbsp;underlying&nbsp;problem.}而是做以下事项:try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;attemptLogin(userCredentials);}&nbsp;catch&nbsp;(SQLException&nbsp;sqle)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;LoginFailureException(sqle);&nbsp;//<--&nbsp;Wrap&nbsp;original&nbsp;exception&nbsp;to&nbsp;pass&nbsp;on&nbsp;root&nbsp;cause&nbsp;upstairs!.}吞噬原始根源会导致实际原因无法恢复,这对于生产支持团队来说是一场噩梦,他们可以访问的是应用程序日志和错误消息。虽然后者是一个更好的设计,但许多人不经常使用它,因为开发人员只是无法将基础消息传递给调用者。所以要做一个坚定的说明:Always pass on the actual exception回复是否包含在任何特定于应用程序的异常中。试试&nbsp;RuntimeExceptionsRuntimeException作为一般规则,不应该试图抓住。它们通常表示编程错误,应该保持不变。相反,程序员应该在调用可能导致a的代码之前检查错误情况RuntimeException。例如:try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;setStatusMessage("Hello&nbsp;Mr.&nbsp;"&nbsp;+&nbsp;userObject.getName()&nbsp;+&nbsp;",&nbsp;Welcome&nbsp;to&nbsp;my&nbsp;site!);}&nbsp;catch&nbsp;(NullPointerException&nbsp;npe)&nbsp;{ &nbsp;&nbsp;&nbsp;sendError("Sorry,&nbsp;your&nbsp;userObject&nbsp;was&nbsp;null.&nbsp;Please&nbsp;contact&nbsp;customer&nbsp;care.");}这是一个糟糕的编程习惯。相反,应该像以下一样进行空检查 -if&nbsp;(userObject&nbsp;!=&nbsp;null)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;setStatusMessage("Hello&nbsp;Mr.&nbsp;"&nbsp;+&nbsp;userObject.getName()&nbsp;+&nbsp;",&nbsp;Welome&nbsp;to&nbsp;my&nbsp;site!);}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;sendError("Sorry,&nbsp;your&nbsp;userObject&nbsp;was&nbsp;null.&nbsp;Please&nbsp;contact&nbsp;customer&nbsp;care.");}但有时候这种错误检查很昂贵,例如数字格式化,请考虑这个 -try&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;userAge&nbsp;=&nbsp;(String)request.getParameter("age"); &nbsp;&nbsp;&nbsp;&nbsp;userObject.setAge(Integer.parseInt(strUserAge));}&nbsp;catch&nbsp;(NumberFormatException&nbsp;npe)&nbsp;{ &nbsp;&nbsp;&nbsp;sendError("Sorry,&nbsp;Age&nbsp;is&nbsp;supposed&nbsp;to&nbsp;be&nbsp;an&nbsp;Integer.&nbsp;Please&nbsp;try&nbsp;again.");}这里预调用错误检查不值得付出努力,因为它本质上意味着复制parseInt()方法中的所有字符串到整数转换代码 - 并且如果由开发人员实现则容易出错。所以最好不要试试try-catch。所以NullPointerException和NumberFormatException都RuntimeExceptions,捉NullPointerException应以优美的空检查更换,而我建议捉NumberFormatException明确,以避免可能的引进容易出错的代码。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java