在Java方法中抛出特定异常是多余的吗?

时间:2014-06-26 14:54:08

标签: java exception methods main

请考虑以下代码段。

public static void main(String [] args) throws IOException
{
    ....
}

我的假设告诉我:任何异常是arrayOutOfBoundsExceptionIOException,程序将被终止,因为没有捕获异常(并且抛出的异常不是一般的)。但是,我确实看到人们在方法签名处抛出特定的异常。

我的问题:这样做有多余? (因为任何异常都会导致程序终止)

如果不是多余的,人们这样做的原因是什么?

2 个答案:

答案 0 :(得分:3)

什么捕获main方法抛出的异常?

  

由于没有捕获异常

,程序将被终止

这似乎是这样的,因为main方法是你的程序启动的地方。但实际上,Java虚拟机(JVM)调用main方法,因此从技术上讲它会捕获并处理由它引发的任何异常。

JVM完成的处理只是在错误流中打印异常的堆栈跟踪,然后终止程序*。这就是为什么你在程序终止之前在控制台中看到堆栈跟踪(除非错误流被重定向到别处,如文件)。

*如果JVM中没有运行其他程序(例如实时非守护程序线程),它也将自行终止。

为什么要宣布?

  

但是我确实看到人们在方法签名处抛出特定的异常。   这样做是多余的吗? (因为任何异常都会导致程序终止)

首先,我应该通过编写throws来澄清,程序员抛出异常。程序员只是声明方法可能抛出此异常,并且方法的调用者必须以某种方式处理它

举个例子:

public static void main(String [] args) throws IOException

这很可能是程序员添加的,因为他的程序从另一个也调用它的类中调用了一些方法。一些常见的例子是:

public FileWriter(String fileName) throws IOException // a constructor can also throw exceptions
FileWriter.write(int c) throws IOException

FileWriter类的设计者已强制其用户(程序员)处理IOException。这称为已检查的例外

两种类型的例外

已检查的异常告诉用户在程序运行期间,导致此异常的方案很可能发生,即使它通常也不应该(因为我们不要生活在一个理想的世界里。这表示环境错误,即使在最佳程序中也可能抛出此异常。

另一种类型的例外是未经检查的例外。您未使用NullPointerException声明throws(未经检查的例外)的原因是因为在正常程序运行期间导致的情况不会发生 。如果发生这种情况,则表明编程错误和编写错误的程序。

您如何处理异常?

有两种方法可以处理方法中收到的异常。

首先是程序员在你的例子中所做的事情。只需将该异常抛回给调用者即可。

其次是使用try-catch块在内部处理它:

public static void main (String [] args) // no need to declare "throws IOException"
{
    try {
        /* some code here that may throw IOException */
    } catch (IOException ioe) {
        System.err.println("Uhhhh something went wrong!");
        // or some logging can happen
        ioe.printStackTrace();
        System.exit(-6); // a custom error signal can be sent in termination
    }
}

但是,为什么呢?

  

如果它不是多余的,人们这样做的原因是什么?

他们这样做是因为Java强制检查要明确处理的异常,而未经检查的异常可能未处理。

正如我已经解释了可以处理异常的两种方式,应该注意程序员可以根据情况选择一种方式。对于某些方法,将一个捕获的异常抛给调用者可能更有意义,而对于其他方法,在内部处理捕获的异常会更有意义。

然后有些懒惰的程序员只用throws声明每个检查过的异常。

备注

可以使用上述两种方法之一处理已检查和未检查的异常。未经检查的异常为您提供了不处理它的第三种选择,这反过来又让调用者可以选择处理或不处理它。

如果使用throws声明未经检查的异常,它将成为方法调用者的已检查异常。

你也可以混合搭配。例如,您可以在方法中的任何位置内部处理已检查的异常,即使它被声明为在方法签名中抛出也是如此。 throws声明仅在内部未处理已检查异常的情况下生效。

类的main方法可以像程序中的任何其他常规静态方法一样调用,只需传入String参数数组即可。它的特殊之处在于,当类作为Java程序启动时,JVM会调用此方法。手动调用main方法时,必须处理可能抛出的已检查异常。

答案 1 :(得分:2)

如果main中的某些代码会引发checked exception(例如IOException),则 throws中声明它。 main方法就像这方面的普通方法一样(实际上,它就像所有方面的常规方法一样,除了它也是程序的入口点)。 / p>