<b>异常:</b>异常是指中断程序正常执行的一种指令流
在JAVA程序中一旦出现了异常,而程序又没有及时处理的情况下,那么程序会中断执行。
<b>例如</b>,观察以下的代码:
public class Demo22{
public static void main(String args[]){
int i = 10 ;
int j = 0 ;
System.out.println(" --------- 计算开始 ---------") ;
<b>System.out.println("i / j = " + (i / j)) ; </b><b>à</b><b> </b><b>此段代码出现了异常</b><b></b>
System.out.println(" --------- 计算结束 ---------") ;
}
};
以上代码编译的时候不存在任何的问题,那么执行时,出错了,打印内容如下:
--------- 计算开始 ---------
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Demo22.main(Demo22.java:6)
整个程序,在出现异常的代码之后不再被执行了,异常之前的程序呢?正确的执行了。
那么在JAVA中我们所处理的异常都属于运行时异常,即:执行JAVA程序的时候出现的错误,那么实际上对于JAVA的异常分类应该按如下的形式划分:
ArithmeticException à RuntimeException à Exception(往往是要由用户自己处理的)
所以对于异常而言,它是一个统称,代表了:
<b>Throwable</b><b>(可能的抛出)</b>
|- <b>Exception</b>:表示需要人为处理的异常,指的是程序的错误 à 因为程序的错误较多,所以就习惯了把所有的错误都统一成为异常。
|- Error:表示JVM错误,人为不能处理
<b>异常的处理格式如下:</b>
try{
包含可能出现错误的代码段 ;
}catch(出错的类型 出错的对象){
对于错误的处理语句 ;
}
那么使用如上的格式修改之前的代码,保证程序可以正确的执行完:
public class Demo23{
try{
System.out.println("i / j = " + (i / j)) ;
}catch(ArithmeticException e){
System.out.println("计算出现了错误。。。") ;
}
但是以上的程序依然存在了些小小的问题,例如:对于计算,往往应该由用户自己输入数据,所以此时可以通过接收参数为其输入数据。代码如下:
public class Demo24{
<b> i = Integer.parseInt(args[0]) ;</b>
<b> j = Integer.parseInt(args[1]) ;</b>
如果现在输入的内容是正确的数字,则程序不会有任何的问题,但是既然数据是由用户自己输入的,那么肯定会输入各种违法的数据。
存在的问题:
· 不输入任何参数,出现数组越界:ArrayIndexOutOfBoundsException
· 输入的参数不是数字,出现了数字格式转换错误:NumberFormatException
· 输入的被除数是0,出现算术错误:ArithmeticException
在以上的错误之中,只有算术错误被处理了,因为在程序上具备了算术错误的处理能力。那么也就意味着,现在的异常处理并不完善,需要加入更多的处理,所以需要编写更多的catch。
以上的程序修改为:
i = Integer.parseInt(args[0]) ;
j = Integer.parseInt(args[1]) ;
System.out.println("算术错误。。。"+e) ;
catch(ArrayIndexOutOfBoundsException e){
System.out.println("没有输入参数。。。"+e) ;
catch(NumberFormatException e){
System.out.println("输入的内容不是数字。。。"+e) ;
但是会发现比较麻烦,因为现在已经知道了的是三个错误,那么对于很多未知道的错误呢?那么此时,就需要分析异常的产生过程。
发现catch中接收的内容都是对象,那么也就意味着,所谓的异常,就是自动产生了一个异常类的实例化对象。一出错就产生。
对象有一个特点,可以向上自动转型,Exception是用户需要处理的最大异常,那么证明所有的对象都可以向Exception转换。
public class Demo25{
catch(Exception e){
System.out.println("其他异常。。。"+e) ;
<b>注意:</b>
如果在程序中出现了多个catch语句,则捕获更粗的catch要放在捕获更细的catch之后。
}<b>catch(Exception e){</b>
<b> System.out.println("</b><b>其他异常。。。</b><b>"+e) ;</b>
<b> }</b>catch(ArithmeticException e){
}catch(ArrayIndexOutOfBoundsException e){
}catch(NumberFormatException e){
则编译的时候出现了以下的错误,说是许多的异常已经被捕获了。
Demo25.java:14: 已捕捉到异常 java.lang.ArithmeticException
catch(ArithmeticException e){
^
Demo25.java:17: 已捕捉到异常 java.lang.ArrayIndexOutOfBoundsException
catch(ArrayIndexOutOfBoundsException e){
Demo25.java:20: 已捕捉到异常 java.lang.NumberFormatException
catch(NumberFormatException e){
3 错误
既然所有异常类的对象都可以向Exception转换,那么是不是直接使用Exception接收更方便?
public class Demo26{
System.out.println("***************************") ;
}catch(<b>Exception e</b>){
System.out.println(e) ;
以上是异常处理的一种格式,实际上异常处理还有另外一种格式,就是说,可以为异常做一个统一的出口,不管是否发生了异常,都要执行此代码:
包含可能出现错误的代码段 ;
对于错误的处理语句 ;
}finally{
不管是否出现异常,都执行此代码 ;
代码如下:
public class Demo27{
}catch(Exception e){
}<b>finally{ </b><b>à</b><b> </b><b>典型的程序出口</b><b></b>
<b> System.out.println("</b><b>不管是否存在异常,此代码都会被执行。。。</b><b>") ;</b>
<b> }</b>
在异常处理中还有两个很重要的关键字
· throws:在方法的声明处使用,表示此方法不处理异常,而交给被调用处处理。
· throw:表示人为的抛出一个异常。
<b>例如:</b>定义一个数学类,里面有一个除法
class Math{
// 此代码有可能发生问题,也有可能不发生问题
// 一旦发生问题,找调用处,谁调用的此方法,谁去处理
public int div(int i,int j) throws Exception{
return i / j ;
public class Demo28{
Math m = new Math() ;
System.out.println(m.div(10,2)) ;
按规定来说,此方法在调用的时候使用异常的捕获,如果不使用,则编译时出现以下的错误提示:
Demo28.java:11: 未报告的异常 java.lang.Exception;必须对其进行捕捉或声明以便抛出
System.out.println(m.div(10,2)) ;
^
1 错误
所以对于调用有throws声明的方法,必须使用try…catch:
System.out.println(m.div(10,0)) ;
问?既然main方法是一个方法,那么能不能在主方法上编写throws语句呢?肯定是可以的
public class Demo29{
public static void main(String args[]) throws Exception{
System.out.println(m.div(10,0)) ;
观察错误的提示:
at Math.div(Demo29.java:5)
at Demo29.main(Demo29.java:11)
可以发现以上的错误提示与不使用try…catch效果是一样的,证明所有的错误都交给了JVM进行处理,实际上在JAVA中默认的处理方式也就是使用JVM完成。
throw:表示在程序中人为的抛出一个异常,而且必须使用try…catch进行处理。
public class Demo30{
throw new Exception("我自己乐意抛。。。") ;
因为对于异常而言,最终结果肯定都是抛出一个异常的实例化对象。所以是自己抛还是系统抛都肯定需要进行异常的捕获及处理。
设计一个除法操作,在操作之前编写:计算开始,在操作之后编写计算结束,中间不管是否出现了错误,都要打印这样两句话,问:该如何实现?
System.out.println(" ======== 计算开始 =========") ;
int temp = 0 ;
temp = i / j ;
throw e ;
}finally{
System.out.println(" ======== 计算结束 =========") ;
return temp ;
public class Demo31{
public static void main(String artgs[]){
try{
System.out.println(m.div(1,0)) ;
一般而言,对于throw、throws、finally往往会一起使用。
<b>自定义异常:</b>
一个类只要继承了Exception就可以称为一个异常类。
class MyException extends Exception{
public MyException(String msg){
super(msg) ;
public class Demo32{
throw new MyException("自己定义玩的。。") ;
<b>注意点:</b>
· throw与throws的区别?
|- throw:是人为抛出异常
|- throws:方法声明处使用,表示在方法中不处理异常
· final与finally
|- final:定义类、方法、常量
|- finally:异常的统一出口
本文转自 李兴华 51CTO博客,原文链接:http://blog.51cto.com/lixinghua/96928,如需转载请自行联系原作者