【问题标题】:Do I have to include catch blocks in Java when calling a method that throws exceptions?调用抛出异常的方法时,是否必须在 Java 中包含 catch 块?
【发布时间】:2012-02-21 04:35:57
【问题描述】:

我创建了一个安卓应用程序。并输入一些代码,就像:

public void onCreate(Bundle savedInstanceState) {
...
XmlResourceParser xrp = getResources().getXml(R.xml.OneXml);   <==OneXml is a custom xml file in folder res/xml
...
try {
    ....
    xrp.next();
    .... 
} catch(IOException e) {
        e.printStackTrace();
} catch(XmlPullParserException e) {
        e.printStackTrace();
} 
...

我发现我既不能删除catch(IOException e) 也不能删除catch(XmlPullParserException e),当我尝试删除其中一个时,Eclipse 在xrp.next() 标记了一个错误并告诉我未处理的异常类型 IOException未处理的异常类型 XmlPullParserException,那么我必须添加两个 catch 吗?为什么 Eclipse 要求我强制添加两个 catch?没有catch这两个代码就不能编译成功吗?

【问题讨论】:

    标签: java android ioexception next


    【解决方案1】:

    这就是已检查异常的含义:您必须要么捕获它们,要么声明它们被抛出。

    onCreate 被覆盖并且必须遵守原始方法的声明,因此要么捕获它们,要么在另一个捕获它们的方法中完成这部分工作,这是你唯一的选择。

    详情请参阅JLS 11 Exceptions,特别是JLS 11.2.3 Exception Checking

    【讨论】:

      【解决方案2】:

      在 Java 中,您必须要么捕获异常,要么声明调用该方法可能导致异常的事实,如下所示:

      public void onSomethingOtherThanCreate(Bundle savedInstanceState) 
        throws IOException, XmlPullParserException
      {
         // your code without any try/catch
      } 
      

      ErrorRuntimeException 随时可能发生的异常不需要这样声明。)

      【讨论】:

      • 你不能随意将throws声明添加到被覆盖的函数中;这不适用于onCreate
      【解决方案3】:

      这不是 Eclipse,而是 Java!

      在方法中,引发异常的代码必须位于 try-catch 块内,除非在方法声明本身中使用了未处理异常的 throws 子句。

      【讨论】:

        【解决方案4】:

        如果你的抱怨是你必须键入 两个 catch 子句,那么可以在一个子句中将它们全部捕获,

        catch (Exception e) {
              // dostuff here
           }
        

        但是,除非您打算做的只是打印堆栈跟踪或记录异常,否则这种做法是不受欢迎的。从长远来看,它会使代码更难调试和维护。

        Java 7 允许您catch multiple exceptions in a single clause,但 Android 尚不支持 Java 7。

        【讨论】:

          【解决方案5】:

          异常处理方式:
          我们可以通过两种方式处理“问题陈述”(问题陈述是任何可以引发异常的陈述)。

          • 将语句括在try-catch 块中。
          • 在方法标头中附加throws 子句。

          在重写方法中处理异常:
          如果您要覆盖子类中的方法。然后您不能在其签名中附加额外的 throws 子句。在您的情况下,onCreate 是父类中的一个方法,它在子类中被覆盖,因此我们不能在它的标题中附加 throws 子句。因此,您必须在 try-catch 块中的 onCreate 方法中包含任何“问题陈述”。

          示例:
          将语句括在try-catch 块中。

          public void myMethod(){
                  try{
                      // Problem Statement
                  }catch(IllegalAccessException e){
                      e.printStackTrace();
                  }catch(NullPointerException e){
                      e.printStackTrace();
                  }
              }
          

          在方法头中附加一个throws 子句。

          public void myMethod()
                  throws IllegalAccessException, NullPointerException{
                      // Problem Statement
              }
          

          示例覆盖方法:
          有效的 throws 子句:如果覆盖方法中的 throws 子句也在父方法中,则它是有效的。

          public class Parent {
              public int method() 
                  throws IllegalAccessException,NullPointerException, Exception {
                  return 0;
              }
          }
          public class child extends Parent {
              // throws is part of method because parent method
              // have throws clause
              @Override
              public int method() 
                  throws IllegalAccessException, NullPointerException,
                      Exception {
                      //Problem Statement
                  return super.method();
              }
          }
          

          无效的 throws 子句:如果父方法中不存在 throws 子句,则被覆盖的方法中的子句无效。

          public class Parent {
              public int method(){
                  return 0;
              }
          }
          
          public class child extends Parent {
              //**Error:** We can not append throws clause in the method because
              // parent method do not have a throws clause
              @Override
              public int method() 
                  throws IllegalAccessException, NullPointerException,
                      Exception {
                      //Problem Statement
                  return super.method();
              }
          }
          

          因此我们必须修改子类的方法并删除 throws 子句,因为在这种特殊情况下父方法不包含 throws 子句。我们必须通过try-catch 块来处理异常。

          public class child extends Parent {
              //**Error:** We can not append throws clause in the method because
              // parent method do not have a throws clause
              @Override
              public int method() {
                  try{
                      // Problem Statement
                  }catch(IllegalAccessException e){
                      e.printStackTrace();
                  }catch(NullPointerException e){
                      e.printStackTrace();
                  }
              }
          }
          

          【讨论】:

          • 我没有对答案投反对票的习惯,尤其是详细的答案,但是对于最终是一个非常简单的问题来说,这方式的信息太多了。更多的话!=更好的答案。这与个人无关,我只是觉得所有多余的措辞都无法解释。
          • (如果它没有将我认为更好的答案推到首屏,我就不会打扰了。)
          • 其实真的很长,但是你的一些代码启发了我,我发现是什么让我感到困惑。事实上,我不知道 xrp.next() 抛出了两个异常,我必须在什么时候捕获它们我调用该函数。也许这里的每个人都试图告诉我真相,但这是你激励我。谢谢。也感谢@DaveNewton,你的热情:)
          猜你喜欢
          • 1970-01-01
          • 2010-10-15
          • 1970-01-01
          • 2018-05-15
          • 1970-01-01
          • 2011-03-25
          • 2011-03-18
          • 1970-01-01
          相关资源
          最近更新 更多