为什么在调用函数时需要“抛出异常”?

时间:2022-09-11 19:51:47
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();
    }
}

Why compiler reports that methods show2(), show3(), and main() have

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

unreported exception Exception that must be caught or declared to be thrown

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

when I remove throws Exception from these methods?

当我从这些方法中删除抛出异常时?

6 个解决方案

#1


101  

In Java, as you may know, exceptions can be categorized into two: One that needs the throws clause or must be handled if you don't specify one and another one that doesn't. Now, see the following figure:

在Java中,您可能知道,异常可以分为两类:一类需要抛出子句,另一类不指定,则必须处理。如下图所示:

为什么在调用函数时需要“抛出异常”?

In Java, you can throw anything that extends the Throwable class. However, you don't need to specify a throws clause for all classes. Specifically, classes that are either an Error or RuntimeException or any of the subclasses of these two. In your case Exception is not a subclass of an Error or RuntimeException. So, it is a checked exception and must be specified in the throws clause, if you don't handle that particular exception. That is why you needed the throws clause.

在Java中,可以抛出任何扩展可抛出类的东西。但是,您不需要为所有类指定一个throw子句。具体地说,是错误或运行时异常或这两个类的任何子类的类。在这种情况下,异常不是错误或运行时异常的子类。因此,这是一个已检查的异常,如果不处理该异常,则必须在throw子句中指定它。这就是您需要抛出子句的原因。


From Java Tutorial:

从Java教程:

An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.

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

Now, as you know exceptions are classified into two: checked and unchecked. Why these classification?

现在,正如您所知道的,异常被分为两类:检查和检查。为什么这些分类?

Checked Exception: They are used to represent problems that can be recovered during the execution of the program. They usually are not the programmer's fault. For example, a file specified by user is not readable, or no network connection available, etc., In all these cases, our program doesn't need to exit, instead it can take actions like alerting the user, or go into a fallback mechanism(like offline working when network not available), etc.

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

Unchecked Exceptions: They again can be divided into two: Errors and RuntimeExceptions. One reason for them to be unchecked is that they are numerous in number, and required to handle all of them will clutter our programm and reduce its clarity. The other reason is:

未检查的异常:它们又可以分为两个:错误和运行时异常。他们不受约束的一个原因是,他们数量众多,而且需要处理所有的问题,这将使我们的项目变得混乱,并降低其清晰度。另一个原因是:

  • Runtime Exceptions: They usually happen due to programmers fault. For example, if an ArithmeticException of division by zero occurs or an ArrayIndexOutOfBoundsException occurs, it is because we are not careful enough in our coding. They happen usually because some errors in our program logic. So, they must be cleared before our program enters into production mode. They are unchecked in the sense that, our program must fail when it occurs, so that we programmers can resolve it at the time of development and testing itself.

    运行时异常:它们通常是由于程序员的错误而发生的。例如,如果出现除法为零的算术异常,或者出现ArrayIndexOutOfBoundsException,那是因为我们在编码时不够小心。它们的发生通常是因为程序逻辑中的一些错误。因此,在我们的程序进入生产模式之前,它们必须被清除。它们是不受检查的,因为我们的程序在发生时必须失败,这样我们程序员就可以在开发和测试时解决它。

  • Errors: Errors are situations from which usually the program cannot recover. For example, if a *Error occurs, our program cannot do much, such as increase the size of program's function calling stack. Or if an OutOfMemoryError occurs, we cannot do much to increase the amount of RAM available to our program. In such cases, it is better to exit the program. That is why they are made unchecked.

    错误:错误是程序通常无法恢复的情况。例如,如果发生*Error,我们的程序就不能做很多事情,比如增加程序的函数调用堆栈的大小。或者,如果发生OutOfMemoryError错误,我们就无法增加程序可用的RAM数量。在这种情况下,最好退出程序。这就是为什么他们不受约束的原因。

For detailed information see:

详细信息参见:

#2


19  

Java requires that you handle or declare all exceptions. If you are not handling an Exception using a try/catch block then it must be declared in the method's signature.

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

For example:

例如:

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

Should be written as:

应该写成:

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

This way you can get rid of the "throws Exception" declaration in the method declaration.

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

#3


3  

Exception is a checked exception class. Therefore, any code that calls a method that declares that it throws Exception must handle or declare it.

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

#4


3  

The throws Exception declaration is an automated way of keeping track of methods that might throw an exception for anticipated but unavoidable reasons. The declaration is typically specific about the type or types of exceptions that may be thrown such as throws IOException or throws IOException, MyException.

抛出异常声明是一种自动跟踪方法的方法,这些方法可能由于预期但不可避免的原因抛出异常。声明通常针对可能抛出的异常类型或类型,例如抛出IOException或抛出IOException, MyException。

We all have or will eventually write code that stops unexpectedly and reports an exception due to something we did not anticipate before running the program, like division by zero or index out of bounds. Since the errors were not expected by the method, they could not be "caught" and handled with a try catch clause. Any unsuspecting users of the method would also not know of this possibility and their programs would also stop.

我们都有或最终会编写一些代码,这些代码会意外地停止,并报告一个异常,原因是我们在运行程序之前没有预料到的事情,比如除数为0或索引越界。由于该方法不期望出现错误,因此不能“捕获”错误并使用try catch子句处理错误。任何不知情的用户也不会知道这种可能性,他们的程序也会停止。

When the programmer knows certain types of errors may occur but would like to handle these exceptions outside of the method, the method can "throw" one or more types of exceptions to the calling method instead of handling them. If the programmer did not declare that the method (might) throw an exception (or if Java did not have the ability to declare it), the compiler could not know and it would be up to the future user of the method to know about, catch and handle any exceptions the method might throw. Since programs can have many layers of methods written by many different programs, it becomes difficult (impossible) to keep track of which methods might throw exceptions.

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

Even though Java has the ability to declare exceptions, you can still write a new method with unhandled and undeclared exceptions, and Java will compile it and you can run it and hope for the best. What Java won't let you do is compile your new method if it uses a method that has been declared as throwing exception(s), unless you either handle the declared exception(s) in your method or declare your method as throwing the same exception(s) or if there are multiple exceptions, you can handle some and throw the rest.

即使Java有声明异常的能力,您仍然可以编写一个带有未处理和未声明异常的新方法,Java将编译它,并且您可以运行它并期望得到最好的结果。Java不会让你做的是编译你的新方法,如果它使用一个方法被声明为抛出异常(s),除非你要么处理声明的异常(s)在你的方法或声明方法抛出相同的异常(s)或如果有多个异常,您可以处理一些,把休息。

When a programmer declares that the method throws a specific type of exception, it is just an automated way of warning other programmers using the method that an exception is possible. The programmer can then decide to handled the exception or pass on the warning by declaring the calling method as also throwing the same exception. Since the compiler has been warned the exception is possible in this new method, it can automatically check if future callers of the new method handle the exception or declare it and enforcing one or the other to happen.

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

The nice thing about this type of solution is that when the compiler reports Error: Unhandled exception type java.io.IOException it gives the file and line number of the method that was declared to throw the exception. You can then choose to simply pass the buck and declare your method also "throws IOException". This can be done all the way up to main method where it would then cause the program to stop and report the exception to the user. However, it is better to catch the exception and deal with it in a nice way such as explaining to the user what has happened and how to fix it. When a method does catch and handle the exception, it no longer has to declare the exception. The buck stops there so to speak.

这种解决方案的好处是,当编译器报告错误时:未处理的异常类型java.io。它给出了声明抛出异常的方法的文件和行号。然后,您可以选择简单地传递buck并声明您的方法也“抛出IOException”。这可以一直执行到主方法,然后导致程序停止并向用户报告异常。但是,最好捕获异常并以良好的方式处理它,例如向用户解释发生了什么以及如何修复它。当一个方法捕获并处理异常时,它不再需要声明异常。责任到此为止。

#5


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());
   }
}

Only small changes in your program. What It seems to be misunderstood by many regarding the main issue, is whenever you throw exception you need to handle it, not necessary in the same place ( ex. show1,2,3 method in your program) but you must at first caller method inside the 'main'. in one word, there is 'throw', there must be 'catch/try', even if not same method where exception happens.

程序中只有很小的变化。对于这个主要问题,它似乎被许多人误解了,当您抛出异常时,您需要处理它,而不是在相同的地方(例如,程序中的show1、2、3方法),但是您必须首先在“main”中使用调用方方法。在一个单词中,有“throw”,必须有“catch/try”,即使是不相同的方法,也有例外。

#6


0  

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

As there is checked exception in show() method , which is not being handled in that method so we use throws keyword for propagating the Exception.

由于show()方法中有一个已检查的异常,该方法没有处理该异常,所以我们使用了throw关键字来传播该异常。

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

Since you are using the show() method in show2() method and you have propagated the exception atleast you should be handling here. If you are not handling the Exception here , then you are using throws keyword. So that is the reason for using throws keyword at the method signature.

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

#1


101  

In Java, as you may know, exceptions can be categorized into two: One that needs the throws clause or must be handled if you don't specify one and another one that doesn't. Now, see the following figure:

在Java中,您可能知道,异常可以分为两类:一类需要抛出子句,另一类不指定,则必须处理。如下图所示:

为什么在调用函数时需要“抛出异常”?

In Java, you can throw anything that extends the Throwable class. However, you don't need to specify a throws clause for all classes. Specifically, classes that are either an Error or RuntimeException or any of the subclasses of these two. In your case Exception is not a subclass of an Error or RuntimeException. So, it is a checked exception and must be specified in the throws clause, if you don't handle that particular exception. That is why you needed the throws clause.

在Java中,可以抛出任何扩展可抛出类的东西。但是,您不需要为所有类指定一个throw子句。具体地说,是错误或运行时异常或这两个类的任何子类的类。在这种情况下,异常不是错误或运行时异常的子类。因此,这是一个已检查的异常,如果不处理该异常,则必须在throw子句中指定它。这就是您需要抛出子句的原因。


From Java Tutorial:

从Java教程:

An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.

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

Now, as you know exceptions are classified into two: checked and unchecked. Why these classification?

现在,正如您所知道的,异常被分为两类:检查和检查。为什么这些分类?

Checked Exception: They are used to represent problems that can be recovered during the execution of the program. They usually are not the programmer's fault. For example, a file specified by user is not readable, or no network connection available, etc., In all these cases, our program doesn't need to exit, instead it can take actions like alerting the user, or go into a fallback mechanism(like offline working when network not available), etc.

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

Unchecked Exceptions: They again can be divided into two: Errors and RuntimeExceptions. One reason for them to be unchecked is that they are numerous in number, and required to handle all of them will clutter our programm and reduce its clarity. The other reason is:

未检查的异常:它们又可以分为两个:错误和运行时异常。他们不受约束的一个原因是,他们数量众多,而且需要处理所有的问题,这将使我们的项目变得混乱,并降低其清晰度。另一个原因是:

  • Runtime Exceptions: They usually happen due to programmers fault. For example, if an ArithmeticException of division by zero occurs or an ArrayIndexOutOfBoundsException occurs, it is because we are not careful enough in our coding. They happen usually because some errors in our program logic. So, they must be cleared before our program enters into production mode. They are unchecked in the sense that, our program must fail when it occurs, so that we programmers can resolve it at the time of development and testing itself.

    运行时异常:它们通常是由于程序员的错误而发生的。例如,如果出现除法为零的算术异常,或者出现ArrayIndexOutOfBoundsException,那是因为我们在编码时不够小心。它们的发生通常是因为程序逻辑中的一些错误。因此,在我们的程序进入生产模式之前,它们必须被清除。它们是不受检查的,因为我们的程序在发生时必须失败,这样我们程序员就可以在开发和测试时解决它。

  • Errors: Errors are situations from which usually the program cannot recover. For example, if a *Error occurs, our program cannot do much, such as increase the size of program's function calling stack. Or if an OutOfMemoryError occurs, we cannot do much to increase the amount of RAM available to our program. In such cases, it is better to exit the program. That is why they are made unchecked.

    错误:错误是程序通常无法恢复的情况。例如,如果发生*Error,我们的程序就不能做很多事情,比如增加程序的函数调用堆栈的大小。或者,如果发生OutOfMemoryError错误,我们就无法增加程序可用的RAM数量。在这种情况下,最好退出程序。这就是为什么他们不受约束的原因。

For detailed information see:

详细信息参见:

#2


19  

Java requires that you handle or declare all exceptions. If you are not handling an Exception using a try/catch block then it must be declared in the method's signature.

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

For example:

例如:

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

Should be written as:

应该写成:

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

This way you can get rid of the "throws Exception" declaration in the method declaration.

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

#3


3  

Exception is a checked exception class. Therefore, any code that calls a method that declares that it throws Exception must handle or declare it.

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

#4


3  

The throws Exception declaration is an automated way of keeping track of methods that might throw an exception for anticipated but unavoidable reasons. The declaration is typically specific about the type or types of exceptions that may be thrown such as throws IOException or throws IOException, MyException.

抛出异常声明是一种自动跟踪方法的方法,这些方法可能由于预期但不可避免的原因抛出异常。声明通常针对可能抛出的异常类型或类型,例如抛出IOException或抛出IOException, MyException。

We all have or will eventually write code that stops unexpectedly and reports an exception due to something we did not anticipate before running the program, like division by zero or index out of bounds. Since the errors were not expected by the method, they could not be "caught" and handled with a try catch clause. Any unsuspecting users of the method would also not know of this possibility and their programs would also stop.

我们都有或最终会编写一些代码,这些代码会意外地停止,并报告一个异常,原因是我们在运行程序之前没有预料到的事情,比如除数为0或索引越界。由于该方法不期望出现错误,因此不能“捕获”错误并使用try catch子句处理错误。任何不知情的用户也不会知道这种可能性,他们的程序也会停止。

When the programmer knows certain types of errors may occur but would like to handle these exceptions outside of the method, the method can "throw" one or more types of exceptions to the calling method instead of handling them. If the programmer did not declare that the method (might) throw an exception (or if Java did not have the ability to declare it), the compiler could not know and it would be up to the future user of the method to know about, catch and handle any exceptions the method might throw. Since programs can have many layers of methods written by many different programs, it becomes difficult (impossible) to keep track of which methods might throw exceptions.

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

Even though Java has the ability to declare exceptions, you can still write a new method with unhandled and undeclared exceptions, and Java will compile it and you can run it and hope for the best. What Java won't let you do is compile your new method if it uses a method that has been declared as throwing exception(s), unless you either handle the declared exception(s) in your method or declare your method as throwing the same exception(s) or if there are multiple exceptions, you can handle some and throw the rest.

即使Java有声明异常的能力,您仍然可以编写一个带有未处理和未声明异常的新方法,Java将编译它,并且您可以运行它并期望得到最好的结果。Java不会让你做的是编译你的新方法,如果它使用一个方法被声明为抛出异常(s),除非你要么处理声明的异常(s)在你的方法或声明方法抛出相同的异常(s)或如果有多个异常,您可以处理一些,把休息。

When a programmer declares that the method throws a specific type of exception, it is just an automated way of warning other programmers using the method that an exception is possible. The programmer can then decide to handled the exception or pass on the warning by declaring the calling method as also throwing the same exception. Since the compiler has been warned the exception is possible in this new method, it can automatically check if future callers of the new method handle the exception or declare it and enforcing one or the other to happen.

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

The nice thing about this type of solution is that when the compiler reports Error: Unhandled exception type java.io.IOException it gives the file and line number of the method that was declared to throw the exception. You can then choose to simply pass the buck and declare your method also "throws IOException". This can be done all the way up to main method where it would then cause the program to stop and report the exception to the user. However, it is better to catch the exception and deal with it in a nice way such as explaining to the user what has happened and how to fix it. When a method does catch and handle the exception, it no longer has to declare the exception. The buck stops there so to speak.

这种解决方案的好处是,当编译器报告错误时:未处理的异常类型java.io。它给出了声明抛出异常的方法的文件和行号。然后,您可以选择简单地传递buck并声明您的方法也“抛出IOException”。这可以一直执行到主方法,然后导致程序停止并向用户报告异常。但是,最好捕获异常并以良好的方式处理它,例如向用户解释发生了什么以及如何修复它。当一个方法捕获并处理异常时,它不再需要声明异常。责任到此为止。

#5


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());
   }
}

Only small changes in your program. What It seems to be misunderstood by many regarding the main issue, is whenever you throw exception you need to handle it, not necessary in the same place ( ex. show1,2,3 method in your program) but you must at first caller method inside the 'main'. in one word, there is 'throw', there must be 'catch/try', even if not same method where exception happens.

程序中只有很小的变化。对于这个主要问题,它似乎被许多人误解了,当您抛出异常时,您需要处理它,而不是在相同的地方(例如,程序中的show1、2、3方法),但是您必须首先在“main”中使用调用方方法。在一个单词中,有“throw”,必须有“catch/try”,即使是不相同的方法,也有例外。

#6


0  

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

As there is checked exception in show() method , which is not being handled in that method so we use throws keyword for propagating the Exception.

由于show()方法中有一个已检查的异常,该方法没有处理该异常,所以我们使用了throw关键字来传播该异常。

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

Since you are using the show() method in show2() method and you have propagated the exception atleast you should be handling here. If you are not handling the Exception here , then you are using throws keyword. So that is the reason for using throws keyword at the method signature.

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