为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

繁星淼淼 2019-05-25 15:14:33
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中,何时应该创建一个已检查的异常,何时应该是运行时异常?何时选择已检查和未检查的例外
查看完整描述

4 回答

?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

某些东西是否是“已检查的异常”与您是否捕获它或在catch块中执行的操作无关。它是异常类的属性。凡是是的一个子类Exception ,除了RuntimeException和它的子类是经过检查的异常。

Java编译器强制您捕获已检查的异常或在方法签名中声明它们。它本来应该提高程序安全性,但大多数意见似乎是它不值得它创造的设计问题。

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

因为这是例外的全部要点。没有这种可能性,您不需要例外。它们使您能够在您选择的级别处理错误,而不是强迫您在最初发生的低级方法中处理它们。


查看完整回答
反对 回复 2019-05-25
?
慕姐4208626

TA贡献1852条经验 获得超7个赞

  1. 以上是否被认为是一个经过检查的例外?不,你是处理异常的事实并不使它成为一个Checked Exception如果它是一个RuntimeException

  2. RuntimeException一个unchecked exception?是

Checked Exceptionssubclassesjava.lang.Exception Unchecked ExceptionsARE subclassesjava.lang.RuntimeException

抛出已检查异常的调用需要包含在try {}块中,或者在方法调用者的上一级中处理。在这种情况下,当前方法必须声明它抛出所述异常,以便调用者可以做出适当的安排来处理异常。

希望这可以帮助。

问:我应该冒泡确切的异常还是使用Exception掩盖它?

答:是的,这是一个非常好的问题和重要的设计考虑因素。Exception类是一个非常通用的异常类,可用于包装内部低级异常。您最好创建一个自定义异常并将其包装在其中。但是,也是一个重大问题 - 永远不要掩盖潜在的原始根本原因。例如,Don't ever请执行以下操作 -

try {
     attemptLogin(userCredentials);} catch (SQLException sqle) {
     throw new LoginFailureException("Cannot login!!"); //<-- Eat away original root cause, thus obscuring underlying problem.}

而是做以下事项:

try {
     attemptLogin(userCredentials);} catch (SQLException sqle) {
     throw new LoginFailureException(sqle); //<-- Wrap original exception to pass on root cause upstairs!.}

吞噬原始根源会导致实际原因无法恢复,这对于生产支持团队来说是一场噩梦,他们可以访问的是应用程序日志和错误消息。虽然后者是一个更好的设计,但许多人不经常使用它,因为开发人员只是无法将基础消息传递给调用者。所以要做一个坚定的说明:Always pass on the actual exception回复是否包含在任何特定于应用程序的异常中。

试试 RuntimeExceptions

RuntimeException作为一般规则,不应该试图抓住。它们通常表示编程错误,应该保持不变。相反,程序员应该在调用可能导致a的代码之前检查错误情况RuntimeException。例如:

try {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welcome to my site!);} catch (NullPointerException npe) {
   sendError("Sorry, your userObject was null. Please contact customer care.");}

这是一个糟糕的编程习惯。相反,应该像以下一样进行空检查 -

if (userObject != null) {
    setStatusMessage("Hello Mr. " + userObject.getName() + ", Welome to my site!);} else {
   sendError("Sorry, your userObject was null. Please contact customer care.");}

但有时候这种错误检查很昂贵,例如数字格式化,请考虑这个 -

try {
    String userAge = (String)request.getParameter("age");
    userObject.setAge(Integer.parseInt(strUserAge));} catch (NumberFormatException npe) {
   sendError("Sorry, Age is supposed to be an Integer. Please try again.");}

这里预调用错误检查不值得付出努力,因为它本质上意味着复制parseInt()方法中的所有字符串到整数转换代码 - 并且如果由开发人员实现则容易出错。所以最好不要试试try-catch。

所以NullPointerExceptionNumberFormatExceptionRuntimeExceptions,捉NullPointerException应以优美的空检查更换,而我建议捉NumberFormatException明确,以避免可能的引进容易出错的代码。


查看完整回答
反对 回复 2019-05-25
  • 4 回答
  • 0 关注
  • 870 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信