一.异常
1.定义
在程序开发过程中,可能存在各种错误,有些错误是可以避免的,而有些错误却是意想不到的,在Java中把这些可能发生的错误称为异常。
2.异常类的继承关系
从上图可以看出,Throwable类是所有异常类的超类,该类的两个直接子类是Error和Exception。其中,Error及其子类用于指示合理的应用程序不应该试图捕获的严重问题,Exception及其子类给出了合理的应用程序需要捕获的异常。
二.Exception
1.定义
在Java中可以捕获的异常(即Exception 类的子类) 分为可控式异常和运行时异常两种类型。
在Java中把那些可以预知的错误,例如从文件中读取数据、对数据库进行操作等,在程序编译时就能对程序中可能存在的错误进行处理,并给出具体的错误信息,我们把这些错误称为可控式异常。
如图所示:
在Java中有些错误是不能被编译器检测到的,例如,在进行除法运算时,除数为零;试图把一个不是由数字组成的字符串使用Integer类的parseInt()方法转换为整数等,Java的编译器是检测不到的,因而能够正常编译,但是在运行时就会发生异常,我们把这些异常称为运行时异常。
如图所示:
2.异常信息的获取及处理
(1)获取
获取异常信息就好比工厂里某个线路出现故障停电了,电工要从线路中找出故障的原因,就像程序中获取到了异常信息。
在Java中java.langThrowable类是具有异常类的超类,该类提供了获取异常信息的方法。
如图所示:
(2)处理——捕捉
在Java语言中当程序发生异常时,可以使用try...catch、try...catch...finally...或try...finally进行处理。
1>.try...catch
对于程序中可能发生异常的语句,可以将其添加到try...catch语句块中,这样当程序发生异常时,就可以对其进行相应的处理。
try...catch语句块的语法格式如下:
try{
可能发生异常的语句
}catch(Exception){
处理语句
}
try和catch是进行异常处理的关键字;
try和catch之间的两个大括号内是程序需要正常执行但又可能发生异常的语句;
catch后的两个小括号内是程序需要处理的异常类型;
catch磁力后的两个大括号内是对程序发生的异常进行处理的语句 。
2>.try...catch...finally...
对于程序中可能发生异常的语句,可以将其添加到try...catch...finally语句块中,这样当程序发生异常时就可以对其进行相应的处理。
try...catch...finally...语句块的语法格式如下:
try{
需要执行的语句
}catch(Exception ex){
对异常进行处理的语句
}finally{
一定会被处理的语句
}
try、catch和finally是进行异常处理的关键字;
try和catch之间的两个大括号内是程序需要正常执行但又可能发生异常的语句;
catch后的两个小括号内是程序需要处理的异常类型;
catch后的两个大括号内是对程序发生的异常进行处理的语句;
finally后的两个大括号内的语句,不管程序是否发生异常都要执行(也就是说程序执行完try和catch之间的语句或执行完try和catch后两个大括号内的语句都将执行finally后的语句)因此finally语句块通常用于执行垃圾回收、释放资源等操作。
技巧:在Java中进行异常处理时,应该尽量使用finally块进行资源回收,因为在try...catch...finally...语句块中,不营程序是否发生异常,最终都会执行finally语句块,因此可以在finally块中添加释放资源的代码。
3>.try...finally
对于程序中可能发生异常的语句,可以将其添加到try...finally语句块中,这样当程序发生异常时,就可以在finally语块中对其进行相应的处理,另外当程序没有发生异常时,执行完try和finally之间的语句后,也将执行finally语句块中的代码,因此可以在finally语句块中放置一些必须执行的代码。
try...finally语法格式:
try{
需要执行的语句
}finally{
一定会被处理的语句
}
try和finally是进行异常处理的关键字;
try和finally之间的两个大括号内是程序需要正常执行但又可能发生异常的语句;
finally后两个大括号内的语句是不管程序是否发生异常最终都要执行的语句,因此finally语句块通常用于放置程序中必须执行的代码,如关闭数据库连接、关闭IO流等。
说明:在有 try...finally语句块的程序中,只要程序执行了的语句块中的代码,不管try语句块是否发生异常,与该的语句块对应的finally语句块都一定会被执行,因此通常使用finally语句块进行资源释放。
异常类用法:
1 package org.hanqi.ex; 2 3 public class TestException { 4 5 public static void main(String[] args) { 6 7 8 //产生异常 9 10 //除0异常 11 12 //1.捕获 13 14 try 15 { 16 int i=12/10; 17 18 19 //打开一些资源 20 String s=null; 21 22 System.out.println("打开资源"); 23 24 //使用 25 //如果在使用中出现异常 26 27 System.out.println("使用资源"); 28 29 s.length(); 30 31 //关闭资源并释放 32 33 System.out.println("希望一定要执行的释放资源代码"); 34 35 } 36 37 catch(ArithmeticException ex) 38 { 39 //针对特定的异常进行特定的处理 40 41 System.out.println("捕获了ArithmeticException异常"); 42 43 //获取异常信息 44 String str=ex.getMessage(); 45 46 //显示:记录日志 47 System.out.println("异常信息="+str); 48 49 //把异常详细信息输出到控制台 50 ex.printStackTrace(); 51 52 System.out.println(); 53 } 54 55 catch(NullPointerException ex) 56 { 57 //针对特定的异常进行特定的处理 58 59 System.out.println("捕获了NullPointerException异常"); 60 61 //获取异常信息 62 String str=ex.getMessage(); 63 64 //显示:记录日志 65 System.out.println("异常信息="+str); 66 67 //把异常详细信息输出到控制台 68 //ex.printStackTrace(); 69 70 System.out.println(); 71 } 72 73 catch(Exception ex)//所有可捕获的异常 74 { 75 //针对特定的异常进行特定的处理 76 77 System.out.println("捕获了NullPointerException异常"); 78 79 //获取异常信息 80 String str=ex.getMessage(); 81 82 //显示:记录日志 83 System.out.println("异常信息="+str); 84 85 //把异常详细信息输出到控制台 86 ex.printStackTrace(); 87 88 System.out.println(); 89 } 90 91 finally//一定会被执行的代码 92 { 93 //关闭资源并释放 94 95 System.out.println("希望一定要执行的释放资源代码"); 96 } 97 98 try 99 { 100 int j=12/0; 101 } 102 finally 103 { 104 System.out.println("一定要执行的代码"); 105 } 106 107 108 System.out.println("程序继续执行"); 109 } 110 111 }
(3)抛出
对于程序中发生的异常,除了可以使用try...catch语句块处理之外还可以使用throws声明或throw语句抛出异常。
1>使用throws声明抛出异常
throws通常用于方法声明,当方法中可能存在异常,却不想在方法中对异常进行处理时,就可以在声明方法时使用throws声明抛出的异常,然后在调用该方法的其他方法中对异常进行处理(如使用try...catch语句或使用throws声明抛出的异常)。
如果需要使用throws声明抛出多个异常,各异常之间要用逗号分隔。
throws声明抛出异常的语法格式如下:
数据类型 方法名(形参列表) throws 异常类1,异常类2,......异常类n{
方法体;
}
1 package org.hanqi.ex; 2 3 public class MyThrow { 4 5 6 //把throws放在方法的后面,特别声明方法有可能发生的异常 7 //方法本身不处理,交给调用者处理 8 public int chu(int a,int b) throws Exception 9 { 10 11 12 return a/b; 13 } 14 15 public void diaoyong() throws Exception 16 { 17 try 18 { 19 int i =chu(12,0); 20 } 21 catch(Exception e) 22 { 23 //TODO自动生成的catch块 24 //e.printStackTrace(); 25 26 System.out.println("我捕获了异常"+e.getMessage()); 27 28 //主动抛出 29 30 throw e; 31 } 32 } 33 34 public void diaoyong2() throws Exception 35 { 36 int i =chu(12,0); 37 } 38 39 public int test(int a,int b) throws Exception 40 { 41 //数据验证 42 if(b==0) 43 { 44 //自己定义 45 Exception e=new Exception("我自定义的异常信息:第二个参数不能等于0"); 46 47 throw e; 48 } 49 50 return a/b; 51 } 52 53 54 55 public static void main(String[] args) 56 { 57 MyThrow mt=new MyThrow(); 58 59 try { 60 mt.diaoyong(); 61 } 62 catch (Exception e) { 63 // TODO 自动生成的 catch 块 64 e.printStackTrace(); 65 } 66 67 System.out.println("继续运行"); 68 69 try { 70 mt.test(30,10); 71 } catch (Exception e) { 72 73 System.out.println("异常信息:"+e.getMessage()); 74 75 //e.printStackTrace(); 76 } 77 } 78 }