Java 为什么要到处乱扔?

Java 为什么要到处乱扔?,java,checked-exceptions,Java,Checked Exceptions,在试图重构一些I代码时,我试图在catch子句中抛出异常,如下所示- try { .... } catch(Exception exception){ ..... throw exception } 然而,当我试图在“throw exception”行抛出异常时,编译器抱怨说,我需要在一个新的try/catch中包围我的throw子句,就像这样- try { .... } catch (Exception exception) { ..... try { throw e

在试图重构一些I代码时,我试图在catch子句中抛出异常,如下所示-

try {
....
}
catch(Exception exception){
.....
throw exception
}
然而,当我试图在“throw exception”行抛出异常时,编译器抱怨说,我需要在一个新的try/catch中包围我的throw子句,就像这样-

try
{
  ....
}
catch (Exception exception)
{
  .....
  try
  {
    throw exception
  }
  catch (Exception e2)
  {
     ...
  }
}
编译器为什么需要这样做?它提供了什么用途


谢谢

在您的原始代码中,没有任何内容捕获抛出的异常。我可以想象,您要么必须指定您的函数抛出一个异常,要么按照编译器的建议使用另一个try/catch块来捕获它

而不是

public void yourFunction(){
  try {
    ....
  }
  catch(Exception exception){
    .....
    throw exception
  }
}
试一试


在原始代码中,没有任何内容捕获抛出的异常。我可以想象,您要么必须指定您的函数抛出一个异常,要么按照编译器的建议使用另一个try/catch块来捕获它

而不是

public void yourFunction(){
  try {
    ....
  }
  catch(Exception exception){
    .....
    throw exception
  }
}
试一试


异常
java.lang.exception
是已检查的异常。这意味着它必须在封闭方法的
throws
子句中声明,或者在方法体中捕获和处理

但是,在“固定”版本中,您要做的是捕获异常,重新刷新它,然后立即再次捕获它。那没有多大意义

没有看到真正的代码,不清楚真正的解决方案应该是什么,但我认为问题出在原始的
try{…}catch
处理程序中:

  • 如果可能的话,您应该在该点捕获一个更具体的异常,这样当您重新引用它时,它就会被该方法现有的
    throws
    列表覆盖

  • 或者,您可以将异常包装在未检查的异常中,然后抛出该异常

  • 作为最后一种手段,您可以更改方法的签名,使其在抛出列表中包含
    异常
    。但这真的是个坏主意,因为它只是把问题推给了打电话的人。。。并使开发人员/读者处于不知道会出现什么异常的境地


异常
java.lang.exception
是一个已检查的异常。这意味着它必须在封闭方法的
throws
子句中声明,或者在方法体中捕获和处理

但是,在“固定”版本中,您要做的是捕获异常,重新刷新它,然后立即再次捕获它。那没有多大意义

没有看到真正的代码,不清楚真正的解决方案应该是什么,但我认为问题出在原始的
try{…}catch
处理程序中:

  • 如果可能的话,您应该在该点捕获一个更具体的异常,这样当您重新引用它时,它就会被该方法现有的
    throws
    列表覆盖

  • 或者,您可以将异常包装在未检查的异常中,然后抛出该异常

  • 作为最后一种手段,您可以更改方法的签名,使其在抛出列表中包含
    异常
    。但这真的是个坏主意,因为它只是把问题推给了打电话的人。。。并使开发人员/读者处于不知道会出现什么异常的境地


在Java中,检查异常和未检查异常之间存在区别。未经检查的异常基本上可以在代码中的任何位置抛出,如果没有在某个地方捕获到,它将传播到应用程序的入口点,然后停止进程(通常带有错误消息和堆栈跟踪)。checked异常是不同的:编译器不会让您仅仅让它传播,您需要用try-catch块包围任何可能抛出checked异常的代码(如果异常是checked异常类的实例,“throw-exception”是最简单的情况)或者,必须使用“throws”声明标记包含对可能引发选中异常的代码的调用的方法。如果期望的行为是抛出一个未检查的异常,那么您需要将该异常包装到RuntimeException中。如果期望的行为是保持异常处于选中状态,那么您需要向当前方法添加一个throws声明。

在Java中,选中的异常和未选中的异常是有区别的。未经检查的异常基本上可以在代码中的任何位置抛出,如果没有在某个地方捕获到,它将传播到应用程序的入口点,然后停止进程(通常带有错误消息和堆栈跟踪)。checked异常是不同的:编译器不会让您仅仅让它传播,您需要用try-catch块包围任何可能抛出checked异常的代码(如果异常是checked异常类的实例,“throw-exception”是最简单的情况)或者,必须使用“throws”声明标记包含对可能引发选中异常的代码的调用的方法。如果期望的行为是抛出一个未检查的异常,那么您需要将该异常包装到RuntimeException中。如果期望的行为是保持异常处于选中状态,那么您需要向当前方法添加一个throws声明。

我的猜测是,您试图抛出一个异常子类,该异常子类没有被该方法声明为它可以抛出的异常类型

下面的示例有效

package test.example;

public class ExceptionTest {

    public static void main(String[] args) throws Exception{
        try {
            int value = 1/0;
        } catch (Exception e) {
            System.out.println("woops the world is going to end");
            throw e;
        }

    }

}
但是,此示例将给出一个错误

package test.example;

public class ExceptionTest {

    public static void main(String[] args) throws RuntimeException{
        try {
            int value = 1/0;
        } catch (Exception e) {
            System.out.println("woops the world is going to end");
            throw e;
        }

    }

}
注意,在第二个示例中,我只是捕获异常而不是RuntimeException,当我抛出一个未声明的异常时,它不会编译,即使我确实声明了RuntimeException

是的,异常是一个运行时异常,但编译器不知道这一点

刚刚想到了第三个工作示例。这一个也有效,因为您的抛出与您声明的类型相同。(注意,唯一的变化是挡块)

您需要了解这三个答案之间的差异
package test.example;

public class ExceptionTest {

    public static void main(String[] args) throws RuntimeException{
        try {
            int value = 1/0;
        } catch (RuntimeException e) {
            System.out.println("woops the world is going to end");
            throw e;
        }

    }

}