Java 检查与未检查的异常
异常 是指在程序执行过程中,即在运行时发生的不需要的或意外的事件,它扰乱了程序的正常指令流。在Java中,有两种类型的异常。
- 有检查的异常
- 未检查的异常
有检查的异常
这些就是在编译时被检查的异常。如果一个方法中的某些代码抛出了一个检查过的异常,那么这个方法必须处理这个异常,或者它必须使用 throws 关键字来指定这个异常。在检查过的异常中,有两种类型:完全检查和部分检查的异常。完全检查的异常是指它的所有子类也被检查的异常,比如IOException、InterruptedException。部分检查的异常是一个检查过的异常,它的一些子类没有被检查,像Exception。
例如,考虑下面这个Java程序,它打开位于 “C:\test\a.txt “位置的文件并打印其中的前三行。这个程序不能编译,因为函数main()使用了FileReader(),而FileReader()抛出了一个被检查的异常 FileNotFoundException。它还使用了readLine()和close()方法,而这些方法也抛出了有检查意义的IOException异常。
例子
// Java Program to Illustrate Checked Exceptions
// Where FileNotFoundException occurred
// Importing I/O classes
import java.io.*;
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Reading file from path in local directory
FileReader file = new FileReader("C:\\test\\a.txt");
// Creating object as one of ways of taking input
BufferedReader fileInput = new BufferedReader(file);
// Printing first 3 lines of file "C:\test\a.txt"
for (int counter = 0; counter < 3; counter++)
System.out.println(fileInput.readLine());
// Closing file connections
// using close() method
fileInput.close();
}
}
输出
为了解决上述程序,我们需要使用throws来指定一个异常列表,或者使用一个try-catch块。我们在下面的程序中使用了throws。由于 FileNotFoundException是IOException的一个子类,我们可以在throws列表中指定IOException,从而使上述程序在编译器中没有错误。
例子
// Java Program to Illustrate Checked Exceptions
// Where FileNotFoundException does not occur
// Importing I/O classes
import java.io.*;
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
throws IOException
{
// Creating a file and reading from local repository
FileReader file = new FileReader("C:\\test\\a.txt");
// Reading content inside a file
BufferedReader fileInput = new BufferedReader(file);
// Printing first 3 lines of file "C:\test\a.txt"
for (int counter = 0; counter < 3; counter++)
System.out.println(fileInput.readLine());
// Closing all file connections
// using close() method
// Good practice to avoid any memory leakage
fileInput.close();
}
}
输出
First three lines of file "C:\test\a.txt"
未检查的异常
这些是在编译时不被检查的异常。在C++中,所有的异常都是未检查的,所以编译器不会强制要求处理或指定异常。这取决于程序员是否文明,并指定或捕获异常。在Java中, Error和 RuntimeException类下的异常是未检查的异常,其他在throwable下的异常都是检查的。
考虑一下下面这个Java程序。它的编译没有问题,但运行时却抛出了ArithmeticException。编译器允许它进行编译,因为 ArithmeticException是一个未检查的异常。
例子
// Java Program to Illustrate Un-checked Exceptions
// Main class
class GFG {
// Main driver method
public static void main(String args[])
{
// Here we are dividing by 0
// which will not be caught at compile time
// as there is no mistake but caught at runtime
// because it is mathematically incorrect
int x = 0;
int y = 10;
int z = y / x;
}
}
输出
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:5)
Java Result: 1
简而言之,未检查的异常是运行时的异常,它们不需要被捕获或在throws子句中声明。这些异常通常是由编程错误引起的,例如试图访问数组中的超界索引或试图除以0。
未检查的异常包括RuntimeException类的所有子类,以及Error类及其子类。
下面是Java中未检查的异常的一些例子。
ArrayIndexOutOfBoundsException: 当你试图访问一个超出边界的数组索引时,会抛出这个异常。
NullPointerException: 当你试图访问一个空对象引用时,会抛出这个异常。
ArithmeticException: 当你试图除以0或执行一个无效的算术操作时,会抛出这个异常。
如果你发现有什么不正确的地方,或者你想分享更多关于上面讨论的主题的信息,请写下评论