Java 我不能抛出特定的异常吗

Java 我不能抛出特定的异常吗,java,Java,上面的示例给出了一个错误“throw new TimeoutException(ex)”和“java.util.concurrent.TimeoutException中的TimeoutException(java.lang.string)不能应用于(java.util.concurrent.TimeoutException)” 但如果我将其替换为“throw new RuntimeException(ex)”,它不会抛出错误 这里大致有三个选项: 重新抛出相同的异常:`throw ex;' 抛出

上面的示例给出了一个错误“throw new TimeoutException(ex)”和“java.util.concurrent.TimeoutException中的TimeoutException(java.lang.string)不能应用于(java.util.concurrent.TimeoutException)”


但如果我将其替换为“throw new RuntimeException(ex)”,它不会抛出错误

这里大致有三个选项:

  • 重新抛出相同的异常:`throw ex;'
  • 抛出新的
    TimeoutException
    并丢失堆栈跟踪:
    抛出新的TimeoutException(例如getMessage())
  • 抛出另一种类型的异常,例如
    RuntimeException
  • 每种选择都有优点和缺点,由您决定

    更新(感谢@Mark Rottenvel)


    第2点可以重写:
    抛出新的TimeoutException(例如getMessage()).initCause(例如)
    保留原始异常的链接。

    我在您的问题中观察到的情况

  • 您正在尝试直接从try缓存块中的类调用方法。这是错误的,您必须创建方法并从中调用它

  • 您想抛出一个异常。因此,您必须从调用它的位置将其抛出方法级别

  • 请在下面找到演示解决方案:

    @Override
    Public class example {
    void test {
    try {
      someMethod(); //This throws TimeoutException
    } catch (TimeoutException ex) {
      throw new TimeoutException(ex); //It doesn't throw error if I replace this with throw new RuntimeException(ex)
    } }
    }
    

    Java有两类异常:已检查和未检查。选中的异常(通常是
    异常的子类
    )必须在函数签名中声明,而未选中的异常(通常是
    运行时异常的子类
    )不能声明


    TimeoutException
    是一个选中的异常。当它可以从未声明它的方法中抛出时,您有2个选项:

    • 在签名中声明:

      public class example {
      
      public void testFunction() throws TimeoutException {
          try {
              someFunction();
          } catch (TimeoutException ex) {
              throw ex; 
          }
      }
      
      public void someFunction() throws TimeoutException {
      
      }
      }
      
      干净简单但可能有问题的是func1是一个未声明的函数的重写以引发此异常,它是从另一个也未声明它的函数(假设来自框架)调用的

    • 将其隐藏在未检查的异常中

      public void func1() throws TimeoutException {
          somefunction();
      }
      
      您将丢失声明性部分(由于该原因存在选中的异常),但至少它允许您从未声明声明声明的函数调用它


    • TimeoutException
      没有接受
      TimeoutException
      作为形式为
      TimeoutException(TimeoutException原因)
      或类似参数的构造函数

      您可以改为:

      public void func1() {
          try {
              somefunction();
          } catch (TimeoutException e) {
              throw new RuntimeException(e);
          }
      }
      
      或者同等地:

      TimeoutException localtoe=new TimeoutException("test failed");
      localtoe.initCause(ex);
      throw localtoe;
      
      initCause()。这是一个有趣的小方法,它的行为就像一个经过思考的构造函数(*)

      将异常包装为异常的原因并不一定是错误的。 假设
      testFunction()
      连接,然后执行一些操作。 根据失败的子步骤,您可能希望抛出一个异常消息“testFunction中的连接失败”和另一个“testFunction中的操作失败”

      但是,如果不需要提供太多细节,您可以
      抛出ex
      ,或者让方法在不捕获任何内容的情况下展开

      这里有一个小例子:

      throw new TimeoutException("test failed").initCause(ex);
      
      预期产出:

      import java.util.concurrent.TimeoutException;
      
      class Example{
      
      private static void connect() throws TimeoutException {
              //Dummy connection that just fails...   
              throw new TimeoutException("connection failed");
          }
      
          private static void process() throws TimeoutException {
              try {
                  connect();
              }catch(TimeoutException toe){
                 TimeoutException toeout=new TimeoutException("process failed because connection failed.");
                 toeout.initCause(toe);
                 throw toeout;
              }
              //Code for when connection succeeds...
          }
      
          public static void main (String[] args) throws java.lang.Exception
          {
              try{
                  process();  
              }catch(TimeoutException toe){
                  System.out.println(toe);
              }
          }
      }
      
      (*)
      initCause()。2002年,它被添加到Java1.4中。文档讨论了“遗留”构造函数。与其将构造函数的数量增加一倍(添加一个带有
      可丢弃原因
      参数的构造函数),不如决定将其作为螺栓连接初始化。
      这是否是最好的解决方案还存在争议。

      java.util.concurrent.TimeoutException没有接受其他异常的构造函数您想在
      TimeoutException
      中打包
      TimeoutException
      。你需要做的是
      抛出ex
      由于这已经是您想要抛出的确切异常,
      TimeoutException
      没有这样的构造函数:@XtremeBaumer,或者根本就没有捕获它。throw ex;说“未处理的异常”时出错。来自AndyTurner:
      或只是不首先捕获它
      (向方法签名添加
      抛出
      )@XtremeBaumer fair Enough前两个选项给出一个错误,说“未处理的异常”。@KishoreKumar yes,这是因为您没有像方法中抛出的那样声明
      TimeoutException
      。您知道
      initCause(Throwable)
      方法的存在吗?这意味着使用选项2,您也不会丢失堆栈跟踪。无需捕获异常并重新抛出它。您可以完全摆脱
      try/catch
      。这样的做法意味着您需要多次记录异常。您通常只记录处理异常的位置,而不是在其中的步骤中。您可能需要考虑不要在另一个<代码> TimeOutExtExabor /代码>中包装“<代码> TimeOutExist< /代码>,因为这不太有意义。这也将简化
      过程()
      ,因为您可以完全取消try-catch。@markrottveel。我建议这样做,并同意将异常包装起来可能有些过分。但我讨厌那些只告诉人们不要做某事而不告诉他们如何做的答案。正如我在回答中所说,您可能有一个方法,该方法有多个步骤,每个步骤都可能超时,并指示哪些步骤失败。连接超时可能与某些操作的环境原因不同。仍然认为这有点过分了,但是没有一个其他的答案提到了
      initCause()
      ,如果你真的觉得需要的话,这就是如何做到的。
      java.util.concurrent.TimeoutException: process failed because connection failed.