阅读时间: 5 分钟
异常处理简介
异常是指在程序执行过程中出现的问题,它可能由于各种原因而发生,例如
- 用户输入了一个无效的数据
- 找不到文件
- 网络连接在通信过程中丢失了
- JVM的内存用完了
异常处理机制遵循一个流程,如下图所示,但如果一个异常没有被处理,可能会导致系统故障。这就是为什么处理异常是非常重要的。
异常的层次结构
所有的异常和错误类型都是Throwable类的子类,它是层次结构的基类。一个分支是以Error为首的,它发生在运行时,另一个分支是Exception,它既可以发生在编译时,也可以发生在运行时。

基本上,Error被Java运行时系统(JVM)用来表示与运行时环境(JRE)相关的错误。 StackOverflowError就是这种错误的一个例子。而Exception则用于用户程序应该捕捉的特殊情况。NullPointerException就是一个例子。
现在你知道什么是错误和异常了,让我们来看看它们之间的基本区别。请看下面的表格,它在两者之间划出了一条清晰的界限。
| 错误 | 异常 |
| 1.不可能从错误中恢复 | 1.有可能从异常中恢复 |
| 2.错误是 "未检查的 "类型。 | 2. 异常可以是 "已检查 "或 "未检查 "的。 |
| 3.在运行时发生 | 3.可以在编译时或运行时发生 |
| 4.由应用程序的运行环境引起 | 4.由应用程序本身引起的 |
现在,,我们将深入研究异常,看看如何处理它们。首先,让我们看看不同类型的异常。
- 检验性异常
这是在编译时发生的,也叫编译时异常。 如果一个方法中的某些代码抛出了一个检查过的异常,那么这个方法必须处理它,或者必须用throws关键字指定这个异常。 - 未检查的异常
这是在执行时发生的。在C++中,所有的异常都是未检查的,所以编译器并不强迫它处理或指定异常。由程序员来指定或捕获这些异常。
异常的基本例子
class Exception{
public static void main(String args[]){
try{
//code that may raise exception
}
catch(Exception e){
// rest of the program
}
}
}
上面的代码代表了一个异常,在尝试块中我们要写一段可能引发异常的代码,然后,这个异常将在捕获块中被处理。
异常的类型
1**.内置**的异常
| 内置异常 | 说明 |
| 算术异常(ArithmeticException | 当算术操作中出现异常情况时,会抛出该异常。 |
| ArrayIndexOutOfBoundsException | 它被抛出以表明一个数组被访问时有一个非法的索引。索引是负数或者大于等于数组的大小。 |
| 未发现类的异常 | 当我们试图访问一个定义未被发现的类时,会产生这个异常。 |
| FileNotFoundException | 当一个文件不能被访问或不能被打开时,会产生一个异常。 |
| IOException | 当输入-输出操作失败或中断时抛出。 |
| InterruptedException | 当一个线程在等待、睡眠或做一些处理时,被中断时抛出。 |
| NoSuchFieldException | 当一个类不包含指定的字段(或变量)时,它被抛出。 |
- **用户定义的异常
**有时,Java中内置的异常无法描述某种情况。在这种情况下,用户也可以创建被称为 "用户定义的异常 "的异常。
需要注意的关键点。- 一个用户定义的异常必须扩展Exception类。
- 它是用throw关键字抛出的。
例子。
class MyException extends Exception{
String str1;
MyException(String str2) {str1=str2;}
public String toString(){
return ("MyException Occurred: "+str1);
}
}
class Example1{
public static void main(String args[]){
try{
System.out.println("Start of try block");
throw new MyException(“Error Message");
}
catch(MyException exp){System.out.println("Catch Block");
System.out.println(exp);
}
}
现在你已经看到了不同类型的异常,让我们深入到这个博客中,了解处理这些异常的各种方法。
异常处理方法
如何在Java中处理异常?
正如我已经提到的,处理异常是非常重要的,否则会导致系统故障,但如何处理这些异常呢?
Java提供了各种处理异常的方法,比如:
- try
- catch
- finally
- throw
- throws
让我们详细了解一下这些方法中的每一个。
尝试块
try块包含一组可能发生异常的语句。它后面总是有一个catch块,用来处理相关try块中发生的异常。一个try块后面必须有catch块或final块或两者。
try{
//code that may throw exception
}catch(Exception_class_Name ref){}
嵌套的try块
在java中,尝试块中的尝试块被称为嵌套尝试块。
class Exception{
public static void main(String args[]){
try{
try{
System.out.println("going to divide");
int b=59/0;
}catch(ArithmeticException e){System.out.println(e);}
try{
int a[]=new int[5];
a[5]=4;
}
catch(ArrayIndexOutOfBoundsException e) {System.out.println(e);}
System.out.println("other statement);
}catch(Exception e)
{System.out.println("Exception handeled");}
System.out.println("casual flow");
}
}
捕获块
catch块是你处理异常的地方。这个块必须跟在try块后面,一个try块可以有几个catch块与之关联,你可以在不同的catch块中捕捉不同的异常,当一个try块中出现异常时,处理该特定异常的相应catch块就会执行。
public class Testtrycatch1{
public static void main(String args[]){
int data=50/0;//may throw exception
System.out.println("rest of the code...");
}
}
SampleMultipleCatchBlock
如果你必须在各种异常发生时执行各种任务,你可以使用多抓块。
public class SampleMultipleCatchBlock{
public static void main(String args[]){
try{
int a[]=new int[5];
a[5]=30/0;
}
catch(ArithmeticException e)
{System.out.println("task1 is completed");}
catch(ArrayIndexOutOfBoundsException e)
{System.out.println("task 2 completed");}
catch(Exception e)
{System.out.println("task 3 completed");}
System.out.println("remaining code");
}
}
finally块
finally块包含了所有的关键语句,无论异常是否发生都必须执行。无论尝试块中是否发生异常,该块中的语句都会执行,例如关闭连接、流等。
class SampleFinallyBlock{
public static void main(String args[]){
try{
int data=55/5;
System.out.println(data);
}
catch(NullPointerException e)
{System.out.println(e);}
finally {System.out.println("finally block is executed");}
System.out.println("remaining code");
}
}
所以,这就是所有关于处理异常的各种方法。
你可能听说过final、finally和finalize是Java中的关键字。是的,它们是,但它们在各方面都有区别。那么,让我们借助下面的表格来看看final、finally和finalize有什么不同。
final vs finally vs finalize
| 最后 | 最后 | 最后确定 |
| 它是一个关键字。 | 它是一个块。 | 它是一个方法。 |
| 用于对类、方法和变量施加限制。 | 用于放置一个重要的代码。 | 用于在对象被垃圾回收之前进行清理处理。 |
| final类不能被继承,方法不能被重写,变量的值不能被改变。 | 无论异常是否被处理,它都会被执行。 | - |
同样,throw和throws听起来很像,但它们是不同的,让我们在下表的帮助下看看。
** throw与throws**
| throw | throws |
| 1.用于明确地抛出一个异常 | 1.用于声明一个异常 |
| 2.被检查的异常不能只用throw来传播 | 2.被检查的异常可以被传播 |
| 3.在一个实例之后 | 3.跟在一个类的后面 |
| 4.在一个方法中使用 | 4.与方法签名一起使用 |
| 5.不能抛出多个异常 | 5.可以声明多个异常 |
//Java throw example
void a()
{
throw new ArithmeticException("Incorrect");
}
//Java throws example
void a()throws ArithmeticException
{
//method code
}
//Java throw and throws example
void a()throws ArithmeticException
{
throw new ArithmeticException("Incorrect");
}
最后,我们结束了关于Java中异常处理的博客。我希望你觉得这篇博客内容丰富,为你的知识增加了价值。
