前面的教程中,我们已经熟悉了 java 中有两种类型的异常:第一种是预定义的异常,第二种是用户定义的异常。
预定义的异常是那些已由 java 系统定义的异常。
所有预定义的异常进一步分为两组:
已检查异常是那些由 java 编译器本身在编译时检查的异常,不在运行时异常类层次结构下。
如果某个方法在程序中引发已检查的异常,则该方法必须处理该异常或将其传递给调用方方法。
我们必须通过使用 try 和 catch 块或在方法声明中使用 throws 子句来处理检查的异常。如果处理不当,它将给出编译时错误。
大多数人都感到困惑,并说检查异常发生在编译时,这是错误的。所有异常始终仅在运行时发生,但有些异常在编译时检测到,而另一些异常在运行时检测到。
Java 编译器在编译时检查的异常在 Java 中称为已检查异常。除运行时异常、错误及其子类之外的所有异常都是检查异常。
注意:编译时错误不是例外。它们会出现错误。在 Java 中,只有运行时错误属于异常。
下面列出了一些重要的检查异常:
让我们举一个示例程序,我们将暂停主线程指定的时间,看看程序执行时会发生什么。
程序代码 1:
package exceptionHandling;
public class CheckedExceptionEx1
{
public static void main(String[] args)
{
System.out.println("Hello Java");
Thread.sleep(1000); // Here, main thread paused for a specified amount of time. // Compilation error.
}
}
Output:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Unhandled exception type InterruptedException
解释:
在上面的代码中,有一个编译错误:“未处理的异常类型中断异常”。这是因为 thread.sleep();方法抛出一个 InterruptedException,该异常尚未由 try-catch 或 throws 子句处理。
由于 InterruptedException 是一个经过检查的异常,由编译器本身检查以在运行时顺利执行程序,因此,我们在编译时出现编译错误-InterruptedException 异常。
为了避免这个编译错误,我们必须使用 try-catch 块或 throws 子句来处理这个检查异常。让我们处理它,看看输出是什么?
程序代码 2:
public class CheckedExceptionEx1
{
public static void main(String[] args)
{
System.out.println("Hello Java");
// Apply the try-catch block to handle checked exception.
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
Output:
Hello Java
正如您在上面的代码中看到的,我们已经使用 try-catch 块处理了检查异常。您也可以使用 throws 子句代替 try-catch 块。
让我们举一个示例程序,其中我们将使用 throws 子句处理 Java 检查异常。
程序代码 3:
package exceptionHandling;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class CheckedExceptionEx
{
public static void main(String[] args) throws FileNotFoundException
{
File file = new File("not_existing_file.txt");
FileInputStream stream = new FileInputStream(file);
}
}
Output:
Exception in thread "main" java.io.FileNotFoundException: not_existing_file.txt
(The system cannot find the file specified)
解释:
在上面的代码中,没有编译错误,因为我们使用 throws 子句处理了检查异常。但是,在运行时,FileNotFoundException异常发生,因为我们正在尝试访问不存在的文件。
Java 中未经检查的异常是由 JVM 而不是 Java 编译器检查的异常。它们发生在程序运行时。
运行时异常类下的所有异常在 Java 中称为未检查异常或运行时异常。
我们可以编写一个 Java 程序并对其进行编译。但是在运行程序之前,我们无法看到未经检查的异常和错误的影响。
这是因为 Java 编译器允许我们编写 Java 程序而无需处理未经检查的异常和错误。
Java 编译器不会在编译时检查运行时异常,无论程序员是否处理它们。
如果方法中发生运行时异常并且程序员不处理它,那么 JVM 将终止程序而不执行其余代码。
下面给出了运行时异常的一些重要示例:
让我们举一个基于 Java 运行时异常的示例程序。
程序代码 4:
public class UncheckedExceptionEx1 {
public static void main(String[ ] args)
{
int x = 10;
int y = 0;
int z = x/y; // runtime exception.
System.out.println(z);
}
}
Output:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at exceptionHandling.UncheckedExceptionEx1.main(UncheckedExceptionEx1.java:9)
你会注意到上面的代码已经成功编译,但是当你去执行它时,它会抛出ArithmeticException。这表明编译期间不会发生运行时异常。
为了避免这个运行时错误,我们必须使用 try-catch 块或 throws 子句来处理这个未经检查的异常。让我们处理它,看看输出是什么?
程序代码 5:
public class HandleRuntimeException {
public static void main(String[] args)
{
int x = 10;
int y = 0;
// Apply try-catch block to handle runtime exception.
try {
int z = x/y; // runtime exception.
System.out.println(z);
} catch(ArithmeticException ae) {
System.out.println("A number cannot be divided by zero");
}
}
}
Output:
A number cannot be divided by zero
在此示例中,我们使用 try-catch 块处理运行时异常,并在控制台上生成用户友好消息。我们还可以使用 throws 子句代替 try-catch 块来处理运行时异常。
让我们再看一个基于未经检查的异常的示例程序。
程序代码 6:
public class UncheckedExceptionEx2 {
public static void main(String[] args)
{
int x[ ] = {1, 2, 3, 4};
/* Here, an array contains only 4 elements, but we will try to * display the value of 6th element.
It should throw * ArrayIndexOutOfBoundsException */
System.out.println(x[6]);
}
}
Output:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
解释:
上面的代码也可以成功编译,但在运行时,我们将得到 ArrayIndexOutOfBoundsException uncheck 异常。当从索引之外访问数组元素时,将引发此异常。
我们可以通过使用 try-catch 块来处理上述代码中发现的异常。使用 try-catch 块,我们可以生成用户友好的消息,以便我们能够纠正此问题。让我们来处理它。
程序代码 7:
public class UncheckedExceptionEx2 {
public static void main(String[] args)
{
try
{
int x[ ] = {1, 2, 3, 4};
System.out.println(x[6]);
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("Specified index does not exist. " + "Please correct the error.");
}
}
}
Output:
Specified index does not exist. Please, correct the error.
Java 中的已检查异常和未检查异常之间存在许多重要差异。它们如下:
1. 直接继承 Throwable 类(运行时异常和错误除外)的类称为检查异常,而直接继承运行时异常的类称为未检查异常。
2. 选中的异常在编译时检查和处理,而未检查的异常在编译时不检查和处理。它们在运行时进行检查。
3. 检查异常的示例包括 IOException、SQLException、ClassNotFoundException 等,而未经检查的异常示例包括 ArithmeticException、ClassCastException、NullPointerException、IllegalArgumentException 等。
4. 当方法中发生已检查的异常时,该方法必须捕获异常或将异常传递给其调用方方法。但是在未经检查的异常的情况下,Java 编译器不会强制捕获异常或在 throws 子句中声明它。
5. java 中的选中异常扩展了 Exception 类,而未检查的异常扩展了 RuntimeException 类。
6. 当故障率可能更高时,会发生检查异常。而未经检查的异常发生,主要是由于编程错误/错误。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有