120
class throwseg1
{
    void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

    void show2() throws Exception  // Why throws is necessary here ?
    {
        show();
    }

    void show3() throws Exception  // Why throws is necessary here ?
    {
        show2();
    }

    public static void main(String s[]) throws Exception  // Why throws is necessary here ?
    {
        throwseg1 o1 = new throwseg1();
        o1.show3();
    }
}

为什么编译器会报告方法show2()、、show3()main()

未报告的异常 必须捕获或声明要抛出的异常

当我throws Exception从这些方法中删除?

4

8 回答 8

170

如您所知,在 Java 中,异常可以分为两种:一种需要throws子句或如果您不指定则必须处理,另一种则不需要。现在,看下图:

在此处输入图像描述

在 Java 中,你可以抛出任何扩展Throwable类的东西。但是,您不需要throws为所有类指定子句。具体来说,是这两者的一个ErrorRuntimeException任何一个子类的类。在您的情况下Exception,它不是Erroror的子类RuntimeExceptionthrows因此,这是一个检查异常,如果您不处理该特定异常,则必须在子句中指定。这就是您需要该throws子句的原因。


来自Java 教程

异常是在程序执行期间发生的事件,它破坏了程序指令的正常流程。

现在,如您所知,异常分为两种:已检查和未检查。为什么要进行这些分类?

Checked Exception:它们用于表示在程序执行过程中可以恢复的问题。它们通常不是程序员的错。例如,用户指定的文件不可读,或没有可用的网络连接等,在所有这些情况下,我们的程序都不需要退出,而是可以采取诸如警告用户之类的操作,或者进入回退机制(如网络不可用时离线工作)等。

Unchecked Exceptions:它们又可以分为两种:Errors 和 RuntimeExceptions。不检查它们的一个原因是它们数量众多,并且需要处理所有这些会使我们的程序混乱并降低其清晰度。另一个原因是:

  • 运行时异常:它们通常是由于程序员的错误而发生的。例如,如果出现ArithmeticException除以零或出现an ArrayIndexOutOfBoundsException,那是因为我们在编码时不够仔细。它们的发生通常是因为我们的程序逻辑中的一些错误。因此,必须在我们的程序进入生产模式之前清除它们。从某种意义上说,它们是未经检查的,我们的程序在发生时必须失败,以便我们程序员可以在开发和测试时自行解决它。

  • 错误:错误是程序通常无法从中恢复的情况。例如,如果StackOverflowError发生了a,我们的程序就不能做很多事情,比如增加程序的函数调用堆栈的大小。或者,如果OutOfMemoryError发生这种情况,我们无法做太多事情来增加程序可用的 RAM 量。在这种情况下,最好退出程序。这就是为什么它们不受检查。

有关详细信息,请参阅:

于 2012-07-21T04:11:04.287 回答
32

Java 要求您处理或声明所有异常。如果您没有使用 try/catch 块处理异常,则必须在方法的签名中声明它。

例如:

class throwseg1 {
    void show() throws Exception {
        throw new Exception();
    }
}

应该写成:

class throwseg1 {
    void show() {
        try {
            throw new Exception();
        } catch(Exception e) {
            // code to handle the exception
        }
    }
}

这样您就可以摆脱方法声明中的“抛出异常”声明。

于 2012-07-21T04:13:38.323 回答
6

throws Exception声明是一种自动跟踪可能由于预期但不可避免的原因而引发异常的方法的方法。声明通常特定于可能抛出的异常类型,例如throws IOExceptionthrows IOException, MyException

由于我们在运行程序之前没有预料到的事情,例如被零除或索引越界,我们都已经或最终会编写意外停止并报告异常的代码。由于该方法没有预料到错误,因此无法“捕获”并使用 try catch 子句进行处理。该方法的任何毫无戒心的用户也不会知道这种可能性,他们的程序也会停止。

当程序员知道可能会发生某些类型的错误但想在方法之外处理这些异常时,该方法可以向调用方法“抛出”一种或多种类型的异常而不是处理它们。如果程序员没有声明该方法(可能)抛出异常(或者如果 Java 没有声明它的能力),编译器无法知道,这将由该方法的未来用户知道,捕获并处理该方法可能抛出的任何异常。由于程序可以具有由许多不同程序编写的多层方法,因此很难(不可能)跟踪哪些方法可能引发异常。

即使 Java 具有声明异常的能力,您仍然可以编写一个带有未处理和未声明异常的新方法,Java 将编译它,您可以运行它并希望最好。Java 不会让你做的是编译你的新方法,如果它使用一个被声明为抛出异常的方法,除非你在你的方法中处理声明的异常或者声明你的方法抛出相同的异常或者如果有多个异常,您可以处理一些并抛出其余的。

当程序员声明该方法抛出特定类型的异常时,它只是一种自动警告使用该方法的其他程序员可能发生异常的方法。然后,程序员可以通过声明调用方法也抛出相同的异常来决定处理异常或传递警告。由于编译器已被警告此新方法中可能出现异常,它可以自动检查新方法的未来调用者是否处理异常或声明它并强制其中一个或另一个发生。

这种类型的解决方案的好处是,当编译器报告时,Error: Unhandled exception type java.io.IOException它会给出声明抛出异常的方法的文件和行号。然后,您可以选择简单地推卸责任并声明您的方法也“抛出 IOException”。这可以一直执行到 main 方法,然后它会导致程序停止并向用户报告异常。但是,最好捕获异常并以一种很好的方式处理它,例如向用户解释发生了什么以及如何修复它。当方法确实捕获并处理异常时,它不再需要声明异常。可以这么说,降压止步于此。

于 2013-11-15T18:18:39.427 回答
4

Exception是一个检查异常类。因此,任何调用声明它throws Exception必须处理或声明它的方法的代码。

于 2012-07-21T03:53:50.630 回答
0
void show() throws Exception
{
    throw new Exception("my.own.Exception");
}

由于 show() 方法中存在已检查异常,该方法未处理该异常,因此我们使用 throws 关键字来传播异常。

void show2() throws Exception //Why throws is necessary here ?
{
show();
}

由于您在 show2() 方法中使用了 show() 方法,并且您已经传播了至少应该在此处处理的异常。如果您没有在此处处理 Exception ,那么您正在使用 throws 关键字。这就是在方法签名处使用 throws 关键字的原因。

于 2018-04-08T17:43:33.997 回答
0

基本上,如果您没有在抛出异常的地方处理异常,那么您可以在函数定义处使用“抛出异常”。

于 2019-06-18T12:53:21.273 回答
0

如果通过在当前方法的签名中声明 throws 指令来传播异常,则必须在行或调用堆栈的某处使用 try/catch 构造来处理异常。

于 2019-07-26T12:07:17.157 回答
0
package javaexception;


public class JavaException {
   void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

void show2() throws Exception  // Why throws is necessary here ?
{
    show();
}

void show3() throws Exception  // Why throws is necessary here ?
{
    show2();
}
public static void main(String[] args) {

   JavaException a = new JavaException();

   try{
   a.show3();
   }catch(Exception e){
       System.out.println(e.getMessage());
   }
}

您的程序中只有很小的变化。关于主要问题,许多人似乎误解了,每当您抛出异常时都需要处理它,而不是在同一个地方(例如程序中的 show1,2,3 方法),但您必须首先调用调用方方法在“主要”内部。总之,有“抛出”,必须有“捕捉/尝试”,即使发生异常的方法不同。

于 2018-03-15T08:11:39.153 回答