简体   繁体   English

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

[英]Why is “throws Exception” necessary when calling a function?

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? 当我从这些方法中删除throws Exception

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. 在Java中,您可能知道,异常可以分为两类:一个需要throws子句,或者如果不指定另一个则必须处理,另一个不需要。 Now, see the following figure: 现在,请看下图:

在此输入图像描述

In Java, you can throw anything that extends the Throwable class. 在Java中,您可以抛出任何扩展Throwable类的东西。 However, you don't need to specify a throws clause for all classes. 但是,您不需要为所有类指定throws子句。 Specifically, classes that are either an Error or RuntimeException or any of the subclasses of these two. 具体来说,是ErrorRuntimeException或这两者的任何子类。 In your case Exception is not a subclass of an Error or RuntimeException . 在您的情况下, Exception不是ErrorRuntimeException的子类。 So, it is a checked exception and must be specified in the throws clause, if you don't handle that particular exception. 因此,它是一个已检查的异常,必须在throws子句中指定,如果您不处理该特定异常。 That is why you needed the throws clause. 这就是你需要throws子句的原因。


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. Checked Exception:它们用于表示在程序执行期间可以恢复的问题。 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. 未经检查的异常:它们可以再次分为两个:错误和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 program and reduce its clarity. 它们不受限制的一个原因是它们数量众多,要求处理所有这些都会使我们的程序混乱并降低其清晰度。 The other reason is: 另一个原因是:

  • Runtime Exceptions: They usually happen due to a fault by the programmer. 运行时异常:它们通常由于程序员的错误而发生。 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. 例如,如果发生除零的ArithmeticException或发生ArrayIndexOutOfBoundsException ,那是因为我们在编码时不够谨慎。 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. 它们是未经检查的,因为我们的程序在发生时必须失败,以便我们的程序员可以在开发和测试时自行解决它。

  • Errors: Errors are situations from which usually the program cannot recover. 错误:错误是通常程序无法恢复的情况。 For example, if a StackOverflowError occurs, our program cannot do much, such as increase the size of program's function calling stack. 例如,如果发生StackOverflowError ,我们的程序不能做太多,比如增加程序函数调用堆栈的大小。 Or if an OutOfMemoryError occurs, we cannot do much to increase the amount of RAM available to our program. 或者如果发生OutOfMemoryError ,我们无法增加程序可用的RAM量。 In such cases, it is better to exit the program. 在这种情况下,最好退出程序。 That is why they are made unchecked. 这就是他们不受限制的原因。

For detailed information see: 详细信息请参阅:

Java requires that you handle or declare all exceptions. Java要求您处理或声明所有异常。 If you are not handling an Exception using a try/catch block then it must be declared in the method's signature. 如果您没有使用try / catch块处理Exception,则必须在方法的签名中声明它。

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. 这样你就可以摆脱方法声明中的“throws Exception”声明。

Exception is a checked exception class. Exception是一个经过检查的异常类。 Therefore, any code that calls a method that declares that it throws Exception must handle or declare it. 因此,任何调用声明它throws Exception的方法的代码都必须处理或声明它。

The throws Exception declaration is an automated way of keeping track of methods that might throw an exception for anticipated but unavoidable reasons. throws Exception声明是一种自动跟踪方法的方法,这些方法可能会因预期但不可避免的原因而抛出异常。 The declaration is typically specific about the type or types of exceptions that may be thrown such as throws IOException or throws IOException, MyException . 声明通常特定于可能抛出的异常的类型或类型,例如throws IOExceptionthrows 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. 由于该方法不期望错误,因此无法使用try catch子句“捕获”它们。 Any unsuspecting users of the method would also not know of this possibility and their programs would also stop. 任何毫无防备的方法用户也不会知道这种可能性,他们的程序也会停止。

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. 如果程序员没有声明方法(可能)抛出异常(或者如果Java没有能力声明它),编译器就无法知道,并且将由该方法的未来用户知道,捕获并处理方法可能抛出的任何异常。 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. 由于程序可以有许多不同程序编写的多层方法,因此很难(不可能)跟踪哪些方法可能会抛出异常。

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. 尽管Java具有声明异常的能力,但您仍然可以使用未处理和未声明的异常编写新方法,Java将对其进行编译,您可以运行它并希望获得最佳效果。 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不允许你做的是编译你的新方法,如果它使用一个被声明为抛出异常的方法,除非你在方法中处理声明的异常或声明你的方法抛出它例外或如果有多个例外,你可以处理一些并抛出其余部分。

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. 关于这种解决方案的Error: Unhandled exception type java.io.IOException是,当编译器报告Error: Unhandled exception type java.io.IOException它会提供声明为抛出异常的方法的文件和行号。 You can then choose to simply pass the buck and declare your method also "throws IOException". 然后,您可以选择简单地传递降压并声明您的方法也“抛出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. 可以说,降压停在那里。

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'. 许多关于主要问题似乎被误解的是,每当你抛出异常时你需要处理它,在同一个地方没有必要(例如程序中的show1,2,3方法),但你必须首先调用方法在'主'里面。 in one word, there is 'throw', there must be 'catch/try', even if not same method where exception happens. 总之,有'throw',必须有'catch / try',即使异常发生的方法不同。

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()方法中检查了异常,该方法没有在该方法中处理,因此我们使用throws关键字来传播Exception。

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. 由于您在show2()方法中使用了show()方法,并且至少传播了异常,因此您应该在此处理。 If you are not handling the Exception here , then you are using throws keyword. 如果您没有在此处理异常,那么您正在使用throws关键字。 So that is the reason for using throws keyword at the method signature. 这就是在方法签名中使用throws关键字的原因。

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

基本上,如果你没有在抛出它的同一个地方处理异常,那么你可以在函数的定义中使用“throws exception”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM