章
目
录
在本Java 异常教程中,了解 Java 中的异常是什么,以及检查异常和未检查异常之间的区别。我们还将学习一些 Java异常处理最佳实践。
1.Java中的异常是什么?
“异常是在程序执行过程中发生的意外事件,它扰乱了正常的指令流。”
- 在Java中,所有错误和异常都是类的类型
Throwable
。 - 当方法内发生错误时,该方法会创建一个对象(或 的任何子类型
Throwable
)并将其交给运行时系统。该对象称为异常对象。 - 异常对象包含有关错误的信息,包括异常类型和错误发生时程序的状态。
- 创建异常对象并将其交给运行时系统称为抛出异常。
程序执行中的异常的一些示例可以是:
- 用户输入字母数字输入,程序不输入数字。
- 程序尝试读取该文件,但指定位置不存在该文件。
- 从 Web 服务读取数据时网络连接终止。
try {
Integer.parseInt("six") ; //This line throws an exception
}
catch(NumberFormatException nfe) {
//handle exception
}
2. 处理抛出的异常
当我们的应用程序中创建异常对象时,我们有两种选择:
- 我们要么使用try-catch块在方法中处理它。
- 或者我们可以将它传递给调用者方法让它处理。
这是在设置方法的职责时需要做出的非常重要的决定。
方法应该清楚地表明它将处理哪些异常,不会处理哪些异常。它是在方法声明中使用throws
关键字定义的。
为了处理异常,我们必须在try-catch块的catch部分捕获异常。
try {
//code
}
catch(Exception e) {
//handle exception
}
如果应用程序中未处理异常,则异常将传播到 JVM。JVM 通常会终止程序。
3.受检异常与非受检异常
在 Java 中,异常大致分为两部分:
- 检查异常
- 未经检查的异常
3.1. 检查异常
顾名思义,受检查的异常是方法必须在其主体中处理或抛出给调用方方法以便调用方方法可以处理它的那些异常。
检查异常由Java编译器检查,因此称为编译时异常。
Java 编译器强制我们在应用程序代码中以某种方式处理这些异常。我们必须在应用程序内适当的级别处理这些异常,以通知用户失败并要求他重试或稍后再来。
通常,已检查异常表示程序直接控制之外的错误情况。这些通常发生在程序与其他系统/网络资源交互时,例如数据库错误、网络连接错误、丢失文件等。
请注意,所有检查异常都是类的子类Exception
。例如,
ClassNotFoundException
IOException
SQLException
检查异常示例
这FileNotFoundException
是 Java 中的受检查异常。任何时候,我们想要从文件系统读取文件时,Java 都会强制我们处理文件可能不存在于该位置的错误情况。
public static void main(String[] args)
{
FileReader file = new FileReader("somefile.txt");
}
在上面的示例中,您将收到编译时错误,并显示消息 – Unhandled exception type FileNotFoundException
。
为了使程序能够编译,我们必须在try-catch块中处理这种错误情况。下面给出的代码绝对可以正常编译。
//读取文件并应用异常处理
public static void main(String[] args)
{
try
{
FileReader file = new FileReader("somefile.txt");
}
catch (FileNotFoundException e)
{
//Alternate logic
e.printStackTrace();
}
}
3.2. 未经检查的异常
编译器不检查未经检查的异常。这些称为运行时异常。一旦执行任何有缺陷的代码,未经检查的异常就会在程序中出现并出现。
在Java中,编译器不会强制成员方法在方法声明中声明未经检查的异常。通常,此类方法几乎总是不声明它们。
未经检查的异常是RuntimeException
类的子类。
ArithmeticException
ArrayStoreException
ClassCastException
奇怪的是,RuntimeException
它本身就是Exception
所有未检查异常类的子类,即所有未检查异常类都应该隐式检查异常,但事实并非如此。”
未经检查的异常示例
给定程序中的代码不会给出任何编译时错误。但是当我们运行该示例时,它会抛出NullPointerException
. NullPointerException是 Java 中的未经检查的异常。
//JVM 不强迫我们检查
NullPointerExceptionpublic static void main(String[] args)
{
try
{
FileReader file = new FileReader("pom.xml");
file = null;
file.read();
}
catch (IOException e)
{
//Alternate logic
e.printStackTrace();
}
}
4. 异常处理最佳实践
- 当方法可能无法执行其必须执行的操作时,可以使用受检异常。例如,名为 的方法
prepareSystem()
预填充配置文件并使用它们进行一些配置。它可以声明抛出FileNotFoundException,这意味着该方法使用文件系统中的配置文件,但它们丢失了。 - 理想情况下,检查异常永远不应该用于编程错误,而绝对应该用于这种情况下的资源错误和流控制。
- 仅抛出方法无论如何都无法处理的异常。该方法一遇到就应该首先尝试处理。仅当无法在方法内部处理异常时才抛出异常。
- 定义方法签名的一个好方法是在方法名称附近声明异常。如果该方法被命名
openFile()
,那么它应该抛出FileNotFoundException
?。如果该方法已命名findProvider()
,则预计会抛出异常NoSuchProviderException
。 - 此外,应该检查这些类型的异常,因为它迫使调用者处理方法语义固有的问题。
- 如果我们要创建任何自定义异常,那么规则是,如果可以合理地期望客户端从异常中恢复,则将其设为已检查异常。如果客户端无法执行任何操作来从异常中恢复,请将其设为未经检查的异常。
5. 结论
在本 Java 教程中,我们了解了 Java 异常。我们通过示例了解了 Java 中检查异常与非检查异常之间的区别,以及如何处理 Java 中非检查异常和异常层次结构。
请记住,检查异常和非检查异常之间的最大区别在于,检查异常是由编译器强制执行的,用于指示程序无法控制的异常情况,而非检查异常是在运行时发生的,用于指示编程错误。