Java 是否可以忽略异常?

Java 是否可以忽略异常?,java,exception,exception-handling,Java,Exception,Exception Handling,在Java中,是否可以使具有抛出语句的方法不被检查 例如: public class TestClass { public static void throwAnException() throws Exception { throw new Exception(); } public static void makeNullPointer() { Object o = null; o.equals(0);//NullPoi

在Java中,是否可以使具有
抛出
语句的方法不被检查

例如:

public class TestClass {
    public static void throwAnException() throws Exception {
        throw new Exception();
    }
    public static void makeNullPointer() {
        Object o = null;
        o.equals(0);//NullPointerException
    }
    public static void exceptionTest() {
        makeNullPointer(); //The compiler allows me not to check this
        throwAnException(); //I'm forced to handle the exception, but I don't want to
    }
}
private class UnlikelyException extends RuntimeException {
    public UnlikelyException (Exception e){
        super (e);
    }
}

否,它会引发编译器错误。作为一个已检查的异常,您必须捕获它,或者通过将您的方法声明为可能引发它来传播它。
检查并重试。

您可以尝试不做任何事情:

public static void exceptionTest() {
    makeNullPointer(); //The compiler allows me not to check this
    try {
        throwAnException(); //I'm forced to handle the exception, but I don't want to
    } catch (Exception e) { /* do nothing */ }
}
记住,在现实生活中,这绝对是不明智的。这可能会隐藏一个错误,让你在问题真的是一只猫(ch)的时候找狗整整一周。(来吧,至少在那里放一个
System.err.println()
日志记录是这里的最佳实践,正如@BaileyS所建议的那样。)

扩展
RuntimeException
类。抛出它们不会要求客户提供
捕获

// notice there's no "throws RuntimeException" at the signature of this method
public static void someMethodThatThrowsRuntimeException() /* no need for throws here */ {
    throw new RuntimeException();
}
扩展
RuntimeException
的类也不需要
throws
声明

关于它:

public static void exceptionTest() {
    makeNullPointer(); //The compiler allows me not to check this
    try {
        throwAnException(); //I'm forced to handle the exception, but I don't want to
    } catch (Exception e) { /* do nothing */ }
}
下面是一条底线指导原则:如果可以合理地期望客户机从异常中恢复,则将其设置为已检查的异常。如果客户端无法从异常中恢复,请将其设置为未检查的异常


据我所知,在这种情况下是不可能的。只有未检查的异常,编译器才能跳到检查。例如RuntimeException。

在Java中,有两种类型,检查异常和未检查异常

  • 是已检查的异常,必须捕获或引发
  • 是一个(编译器不会强制在抛出语句中声明它们)您可以忽略它,但它仍然可能发生在运行时,并且应用程序将崩溃
从文件:

类异常和任何不属于的子类的子类 RuntimeException是选中的异常。需要检查已检查的异常 在方法或构造函数的throws子句中声明,如果可以 由方法或构造函数的执行引发并传播 在方法或构造函数边界之外

从文件中:

RuntimeException是那些可以 在Java虚拟机正常运行期间引发

RuntimeException及其子类是未检查的异常。 未检查的异常不需要在方法或 构造函数的throws子句,如果可以通过执行 方法或构造函数,并在方法或 构造函数边界


抛出一个或一个从
RuntimeException
派生的异常。那么编译器将不会强迫您捕获它。

您可以做三件事:

  • 抛出一个
    RuntimeException
    (或者扩展
    RuntimeException
    ,比如
    NullPointerException
    IllegalArgumentException
    ,…),您不必捕获这些异常,因为它们是未检查的异常

  • 捕获异常而不执行任何操作(不建议):

  • 更改
    exceptionTest()
    声明,说明它抛出了一个
    异常
    ,并让调用它的方法捕获
    异常
    ,然后执行适当的操作:

    public static void exceptionTest() throws Exception {
        makeNullPointer(); //The compiler allows me not to check this
        throwAnException(); //I'm no more forced to handle the exception
    }
    

    • 其他答案是正确的,因为它们正确地告诉您应该做什么,但实际上可以抛出未声明的checked异常。有几种方法可以做到这一点;最简单的是:

      public void methodThatSecretlyThrowsAnException() {
          Thread.currentThread().stop(new Exception());
      }
      
      或者,如果您的目标是包装一个声明其异常的现有方法

      public void methodThatSecretlyThrowsAnException() {
          try {
              methodThatAdmitsItThrowsAnException();
          } catch(final Exception e) {
              Thread.currentThread().stop(e);
          }
      }
      
      try{
      //Your logic goes here
      }
      catch(Exception e)//Exception is generic
      {
      //do nothing
      }
      

      (不用说,你永远不应该这样做。)

      只要捕获一个异常,不要对它做任何事情,保持原样,在你不知道特定异常的情况下捕获通用异常

      public void methodThatSecretlyThrowsAnException() {
          try {
              methodThatAdmitsItThrowsAnException();
          } catch(final Exception e) {
              Thread.currentThread().stop(e);
          }
      }
      
      try{
      //Your logic goes here
      }
      catch(Exception e)//Exception is generic
      {
      //do nothing
      }
      

      即使您完全确定在任何情况下都不会失败,也不建议使用空catch块来避免异常。有时,我们没有意识到人为因素

      如果您确信异常不太可能发生(如果不是不可能的话),您应该创建自己的异常并将意外异常包装在其中

      例如:

      public class TestClass {
          public static void throwAnException() throws Exception {
              throw new Exception();
          }
          public static void makeNullPointer() {
              Object o = null;
              o.equals(0);//NullPointerException
          }
          public static void exceptionTest() {
              makeNullPointer(); //The compiler allows me not to check this
              throwAnException(); //I'm forced to handle the exception, but I don't want to
          }
      }
      
      private class UnlikelyException extends RuntimeException {
          public UnlikelyException (Exception e){
              super (e);
          }
      }
      
      然后用try-catch块包装代码并抛出您不需要捕获的异常

      try {
          // Your code
      } catch  (Exception e) {
          throw new UnlikelyException(e);
      }
      

      您可以使用Java编译器中的漏洞。添加以下代码:

      public RuntimeException hideThrow(Throwable e) {
          if (e == null)
              throw new NullPointerException("e");
          this.<RuntimeException>hideThrow0(e);
          return null;
      }
      
      @SuppressWarnings("unchecked")
      private <GenericThrowable extends Throwable> void hideThrow0(Throwable e) throws GenericThrowable {
          throw (GenericThrowable) e;
      }
      
      公共运行时异常隐藏行(可丢弃){
      如果(e==null)
      抛出新的NullPointerException(“e”);
      这是hideThrow0(e);
      返回null;
      }
      @抑制警告(“未选中”)
      私有void hideThrow0(Throwable e)抛出GenericThrowable{
      投掷(一般可旋转)e;
      }
      

      您可以捕获异常,然后调用异常的
      hideThrow
      ,在编译器没有注意到的情况下抛出它。这是因为类型擦除。在编译时,
      generichrowable
      表示
      RuntimeException
      ,因为这就是我们要传递的。在运行时,
      generichrowable
      表示
      Throwable
      ,因为这是类型参数规范中的基本类型。

      非常好的帖子。我建议的另一件事是,至少在日志记录程序中记录被忽略的异常。我想对这句可怕的双关语投反对票,但我无法让自己这么做+一个好的answer@Craig哦,得了吧,这个双关语把这篇文章带到了一个全新的层次:p这让人想知道他们所说的“合理地被期望恢复”是什么意思。从程序本身的角度来看,如果文件丢失了,可以做的事情不多,但是检查了
      FileNotFoundException
      。程序所能做的最好的事情就是通知用户(假设有一种方法可以向用户获取输出,这可能不适用于计划服务或您所拥有的东西)。如果“通知用户错误”被认为是一种“合理的恢复”,那么程序可以“合理地被期望从任何异常中恢复”,这使得
      RuntimeException
      毫无用处。我认为这一行也许可以更好地解释