请考虑以下代码段。
public static void main(String [] args) throws IOException
{
....
}
我的假设告诉我:任何异常是arrayOutOfBoundsException
或IOException
,程序将被终止,因为没有捕获异常(并且抛出的异常不是一般的)。但是,我确实看到人们在方法签名处抛出特定的异常。
我的问题:这样做有多余? (因为任何异常都会导致程序终止)
如果不是多余的,人们这样做的原因是什么?
答案 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>