首页 > 代码库 > Java面向对象------>try{}catch(){}异常

Java面向对象------>try{}catch(){}异常

在整个异常处理机制中,异常在系统中进行传递,传递到程序员认为合适的
位置,就捕获到该异常,然后进行逻辑处理,使得项目不会因为出现异常而崩溃。
为了捕获异常并对异常进行处理,使用的捕获异常以及处理的语法格式为:
try{
//逻辑代码
}catch(异常类名 参数名){
//处理代码
}
在该语法中,将正常的程序逻辑代码书写在 try 语句块内部进行执行,这些
代码为可能抛出异常的代码,而 catch语句中书写对应的异常类的类名,在 catch
语句块内部书写出现该类型的异常时的处理代码。
程序执行到 try-catch 语句时,如果没有发生异常,则完整执行 try 语句块内
部的所有代码,而 catch 语句块内部的代码不会执行,如果在执行时发生异常,
则从发生异常的代码开始,后续的 try 语句块代码不会执行,而跳转到该类型的
异常对应的 catch 语句块中。
示例代码如下:
String s = "123";
try{
int n = Integer.parseInt(s);
System.out.println(n);
}catch(NumberFormatException e){
System.out.println("该字符串无法转换! ");
}
在 该 示 例 代 码 中 , Integer类 的 parseInt 方 法 可 能 会 抛 出
NumberFormatException,因为 parseInt 方法的声明如下:
public static int parseInt(String s) throws NumberFormatException
这里字符串 s转换为 int没有发生异常,则程序执行完 try语句块内部的代码,
程序的运行结果为: 123
如果将字符串对象 s 的值修改为”abc”,则运行上面的代码,则 parseInt 方法
执行时将抛出 NumberFormatException,则调用 parseInt 方法语句后续的 try 语句
块中的代码不会执行,程序的执行流程跳转到捕获 NumberFormatException异常
catch 语句块内部,然后执行该 catch 语句块内部的代码,则程序的执行结果
是:
该字符串无法转换!
这就是最基本的捕获异常和异常处理的代码结构。使用 try 语句捕获程序执
行时抛出的异常,使用 catch 语句块匹配抛出的异常类型,在 catch 语句块内部
书写异常处理的代码。
在实际程序中,也可以根据异常类型的不同进行不同的处理,这样就需要多
catch 语句块,其结构如下:
try{
//逻辑代码
} catch(异常类名 1 参数名 1){
//处理代码 1
} catch(异常类名 2 参数名 2){
//处理代码 2
}
……
}catch(异常类名 n 参数名 n){
//处理代码 n
}
例如:
String s = "123";
try{
int n = Integer.parseInt(s);
System.out.println(n);
char c = s.charAt(4);
System.out.println(c);
}catch(NumberFormatException e){
System.out.println("该字符串无法转换! ");
}catch(StringIndexOutOfBoundsException e){
System.out.println("字符串索引值越界");
}
在执行时,按照 catch 语句块书写的顺序从上向下进行匹配,直到匹配到合
适的异常就结束 try-catch 语句块的执行。
在实际执行时,就可以根据捕获的异常类型不同,书写不同的异常处理的代
码了。使用该语法时需要注意,如果这些异常类直接存在继承关系,则子类应该
书写在上面,父类应该书写在下面,否则将出现语法错误。例如:
String s = "123";
try{
int n = Integer.parseInt(s);
System.out.println(n);
char c = s.charAt(4);
System.out.println(c);
}catch(Exception e){
}catch(NumberFormatException e){ //语法错误,异常已经被处理
System.out.println("该字符串无法转换! ");
}catch(StringIndexOutOfBoundsException e){ //语法错误,异常已经被处

System.out.println("字符串索引值越界");
}
这里 Exception 类是所有异常类的父类,在匹配时可以匹配到所有的异常,
所有后续的两个异常处理的代码根本不会得到执行,所以将出现语法错误。正确
的代码应该为:
String s = "123";
try{
int n = Integer.parseInt(s);
System.out.println(n);
char c = s.charAt(4);
System.out.println(c);
}catch(NumberFormatException e){
System.out.println("该字符串无法转换! ");
}catch(StringIndexOutOfBoundsException e){
System.out.println("字符串索引值越界");
}catch(Exception e){
}
如果在程序执行时,所有的异常处理的代码都是一样的,则可以使用
Exception 代表所有的异常,而不需要一一进行区分,示例代码如下:
String s = "123";
try{
int n = Integer.parseInt(s);
System.out.println(n);
char c = s.charAt(4);
System.out.println(c);
}catch(Exception e){
//统一的处理代码
}
在实际使用时,由于 try-catch的执行流程,使得无论是 try 语句块还是 catch
语句块都不一定会被完全执行,而有些处理代码则必须得到执行,例如文件的关
闭和网络连接的关闭等,这样如何在 try 语句块和 catch 语句块中都书写则显得
重复,而且容易出现问题,这样在异常处理的语法中专门设计了 finally 语句块来
进行代码的书写。语法保证 finally 语句块内部的代码肯定获得执行,即使在 try
catch 语句块中包含 return 语句也会获得执行,语法格式如下:
finally{
//清理代码
}
该语法可以和上面的两种 try-catch语句块匹配,也可以和 try 语句匹配使用,
try 语句块匹配的语法格式如下:
try{
//逻辑代码
}finally{
//清理代码
}
这样在执行时,无论 try 语句块中的语句是否发生异常, finally 语句块内部
的代码都会获得执行。
而只书写 finally 而不书写 catch 则会导致异常的丢失,所以最常用的异常处
理的语法格式还是如下语法:
try{
//逻辑代码
}catch(异常类名 参数){
//异常处理代码
}finally{
//清理代码
}
这样就是整个异常处理部分的逻辑代码、异常处理代码和清理的代码成为一
个整体,使得程序代码更加显得紧凑,便于代码的阅读和使用。
最后,介绍一下使用异常处理语法时需要注意的问题:
1、书写在 try 语句块内部的代码执行效率比较低。所以在书写代码时,只把可能
出现异常的代码书写在 try 语句块内部。
2、如果逻辑代码中抛出的异常属于 RuntimeException 的子类,则不强制书写在
try 语句块的内部,如果抛出的异常属于非 RuntimeException 的子类,则必须进
行处理,其中书写在 try 语句块是一种常见的处理方式。
3catch语句块中只能捕获 try 语句块中可能抛出的异常,否则将出现语法错误。


声明自定义异常类
如果 JDK API中提供的已有的异常类无法满足实际的使用需要,则可以根据
需要声明自定义的异常类来代表项目中指定类型的异常。
异常类在语法上要求必须直接或间接继承 Exception,可以根据需要选择继承
Exception RuntimeException 类,这样也设定了自定义异常类的类型。如果直
接继承 Exception,则属于必须被处理的异常,如果继承 RuntimeException,则不
强制必须被处理。当然,可以根据需要继承其它 Exception 的子类。
在编码规范上,一般将异常类的类名命名为 XXXException,其中 XXX 用来
代表该异常的作用。
示例代码如下:
/**
* 自定义异常类
*/
public class MyException extends RuntimeException {}
自定义异常类的用途,则完全由程序员进行规定,可以在出现该异常类型的条件
时抛出该异常,则就可以代表该类型的异常了。
在实际的项目中,有些时候还需要设计专门的异常类体系,来代表各种项目中需
要代表的异常情况。

异常处理方式
前面介绍了异常处理机制的相关语法,但是当出现异常时,如何进行处理是
语法无法解决的问题,下面就介绍一下异常处理的方式。
异常处理,顾名思义就是将出现的异常处理掉,但是根据异常出现的位置以
及异常的类型不同,会出现很多的方式,依次介绍如下:
1、不处理
该处理方式就是只捕获异常不进行处理。不推荐使用该方式。
例如:
String s = “abc”;
try{
int n = Integer.parseInt(s);
}catch(Exception e){
}
对于这样的处理,该异常被忽略掉了,有可能会影响后续逻辑的执行执行。该种
处理方式一般被初学者使用的比较多。
2、直接处理掉
如果具备处理异常的条件,则可以根据不同的异常情况将该异常处理掉,例如给
出用户错误原因的提示等或根据逻辑上的需要修正对应的数值。
例如:
/**
* 异常处理示例
* 该程序的功能是将用户输出的命令行参数转换为数字并输出
*/
public class ExceptionHandle1 {
public static void main(String[] args) {
int n = 0;
try{
//将输入的第一个命令行参数转换为数字
n = Integer.parseInt(args[0]);
//输出转换后的结果
System.out.println(n);
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("请输入命令行参数! ");
}catch(NumberFormatException e){
System.out.println("命令行参数不是数字字符串! ");
}
}
}
在执行该代码时,如果发生数组下标越界异常,则代表用户未输入命令行参数,
则提示用户输入命令行参数,如果发生数字格式化异常,则代表用户输入的第一
个命令行参数不是数字字符串,则给出用户对应的提示信息。
该示例中就是根据异常出现的原因提示用户进行正确的操作,这是一种常见的异
常处理的方式。
3、重新抛出
在实际的项目,有些时候也需要将某个方法内部出现的所有异常都转换成项目中
自定义的某个异常类,然后再重新抛出。
例如:
try{
//逻辑代码
}catch(Exception e){
throw new MyException();
}
这样转换以后,比较容易发现异常出现的位置,也方便项目中逻辑
上的处理。
4、在方法中声明
如果当前方法或构造方法中,或在当前方法或构造方法中调用的其它方法,会抛
出某个异常,而在当前方法或构造方法中没有足够的信息对该异常进行处理,则
可以将该异常进行传递,将该异常传递给调用当前方法的位置在进行处理。这就
是异常在系统中传递的方式。
例如:
/**
* 异常处理示例 2
* 演示在方法中重新声明异常
*/
public class ExceptionHandle2 {
public void test(String s) throws NumberFormatException{
int n = Integer.parseInt(s);
System.out.println(n);
}
}
test 方法中,由于 parseInt 方法会抛出 NumberFormatException 异常,而该方
法内部无法对此进行处理,所以则在 test方法内部声明把 NumberFormatException
异常抛出,这样该异常就由调用 test 的方法再进行处理。这样异常就可以在方法
之间进行传递了。
这里列举了异常处理中常见的一些处理方式,当然也可以根据需要,进行其
它的处理。


总结
异常处理是 Java语言中增强程序健壮性的一种机制, Java语法为异常处理提
供了一系列的语法格式,在实际的项目中,需要根据具体的情况对异常给出对应
的处理,使得异常能够被正确的处理掉,从而保证项

Java面向对象------>try{}catch(){}异常