java的异常Exception

1.什么是异常

非正常的,不同于平常的.

       生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.张三要开车去上班,正常情况下,应该是到达公司,上班.不正常的情况下,车子坏了,只能走路去,导致上班迟到.
       程序中:在程序中,代码出现错误,程序就会终止运行.
异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行.
----------------------------------------
异常处理是衡量一门语言是否成熟的标准之一,主流的语言Java,C++,C#等支持异常处理机制.
异常处理机制可以让程序有更好的容错性,使我们的代码更健壮.
遗憾的是传统的C语言却没有异常,此时只能程序员通常使用方法的特定返回值来表示异常情况,并且使用if语句来判断正常和非正常情况,那没有异常会带来什么问题呢?

----------------------------------------
没有异常机制存在的缺点:
1:使用方法的返回值来表示异常情况有限,无法穷举所有的异常情况.
2:异常流程代码和正常流程代码混合一起,增大了程序的复杂性,可读性也不好.

3:随着系统规模的不断扩大,程序的可维护性极低.

2.java的异常体系



1):Error:表示错误,一般指JVM相关的不可修复的错误,如,系统崩溃,内存溢出,JVM错误等,由JVM抛出,我们不需要处理.
           几乎所有的子类都是以Error作为类名的后缀.
2):Exception:表示异常,指程序中出现不正常的情况,该问题可以修复(处理异常).
          几乎所有的子类都是以Exception作为类名的后缀.
----------------------------------------------------------------------------------------------------
出现异常,不要紧张,把异常的简单类名,拷贝到API中去查.
----------------------------------------------------------------------------------------------------
常见的Error:
    StackOverflowError:当应用程序递归太深而发生内存溢出时,抛出该错误。 
常见的Exception:
    NullPointerException
:空指针异常,一般指当对象为null的时候,调用了该对象的方法,字段.
    ArrayIndexOutOfBoundsException:数组的索引越界,(小于0或者大于等于数组长度)
    NumberFormatException:数字格式化异常, 一般指,把非0~9的字符串转换为整数.
--------------------------------------------------------------
证明出现异常之后,程序会中断,所以必须处理异常.

2.捕获异常

如果异常出现的话,会立刻终止程序,所以我们得处理异常:
     1):该方法不处理,而是声明抛出,由该方法的调用者来处理(throws).
     2):在方法中使用try-catch的语句块来处理异常.
-----------------------------------------------------------------------
使用try-catch捕获单个异常,语法如下:
try{
     编写可能会出现异常的代码
}catch(异常类型  e){
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常

}

注意:try和catch都不能单独使用,必须连用.

举例:
1)正常情况
[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         int ret = 10/2;  //正常的结果  
  6.         System.out.println("结果="+ret);  
  7.         System.out.println("end------");  
  8.     }  
  9. }  
2)出现异常,程序会中断执行
[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         int ret = 10/0;  //除数为0,出现异常  
  6.         System.out.println("结果="+ret);  
  7.         System.out.println("end------");  
  8.     }  
  9. }  

可以看出程序出现异常后,程序会终止,这时我们需要处理异常
[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         try{          
  6.             int ret = 10/0;  //除数为0,出现异常  
  7.             System.out.println("结果="+ret);  
  8.         }catch(ArithmeticException e){  
  9.             System.out.println("出异常啦!!!!");  
  10.         }  
  11.         System.out.println("end------");  
  12.     }  
  13. }  


分析:

可以看出异常出现后程序跳转到catch块儿执行,当catch块儿的代码执行完之后,程序并没有停止,而是继续执行后面的代码

3.获取异常信息

如何获取异常信息,Throwable类的方法:
1):String getMessage():获取异常的描述信息,原因(提示给用户的时候,就提示错误原因).
2):String toString():获取异常的类型和异常描述信息(不用).
3):void printStackTrace():打印异常的跟踪栈信息并输出到控制台.  不需要使用System.out.println.
    包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace.
    记住:现在在catch语句块中,必须写:e.printStackTrace();目的:查看异常的具体信息,方便调试和修改.

[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         try{          
  6.             int ret = 10/0;  //除数为0,出现异常  
  7.             System.out.println("结果="+ret);  
  8.         }catch(ArithmeticException e){  
  9.             System.out.println("异常信息"+e.toString());   //异常信息java.lang.ArithmeticException: / by zero  
  10.             System.out.println("异常信息"+e.getMessage());  //异常信息/ by zero  
  11.             //推荐使用下面这个  
  12.             e.printStackTrace();//自带打印功能异常信息,java.lang.ArithmeticException: / by zero  
  13.                                                 //at cn.anyglobe.ExceptionDemo1.main(ExceptionDemo1.java:8)  
  14.         }  
  15.         System.out.println("end------");  
  16.     }  
  17. }  

使用try-catch捕获多个异常:

try{
     编写可能会出现异常的代码
}catch(异常类型A  e){  当try中出现A类型异常,就用该catch来捕获.
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常

}catch(异常类型B  e){  当try中出现B类型异常,就用该catch来捕获.
     处理异常的代码
     //记录日志/打印异常信息/继续抛出异常

}

[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         String sNum1 = "10"//输入的除数  
  6.         String sNum2 = "0"//输入的被除数  
  7.         try{      
  8.             int num1 = Integer.parseInt(sNum1);  
  9.             int num2 = Integer.parseInt(sNum2);  
  10.             int ret = num1/num2;  //除数为0,出现异常  
  11.             System.out.println("结果="+ret);  
  12.         }catch(ArithmeticException e){  
  13.             System.out.println("除数为0");  
  14.         }catch (NumberFormatException e) {  
  15.             System.out.println("类型转换异常");  
  16.         }  
  17.         System.out.println("end------");  
  18.     }  
  19. }  


[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         String sNum1 = "10"//输入的除数  
  6.         String sNum2 = "0"//输入的被除数  
  7.         try{      
  8.             int num1 = Integer.parseInt(sNum1);  
  9.             int num2 = Integer.parseInt(sNum2);  
  10.             int ret = num1/num2;  //除数为0,出现异常  
  11.             System.out.println("结果="+ret);  
  12.         }catch(ArithmeticException e){  
  13.             System.out.println("除数为0");  
  14.         }catch (NumberFormatException e) {  
  15.             System.out.println("类型转换异常");  
  16.         }  
  17.         System.out.println("end------");  
  18.     }  
  19. }  

从上面两个代码可以看出,捕获多个异常时,程序只需要一个catch捕获,不可能同时出现多个异常.

如果不知道什么异常的话可以用父类接收
[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         String sNum1 = "10"//输入的除数  
  6.         String sNum2 = "0"//输入的被除数  
  7.         try {  
  8.             //String转换为int类型  
  9.             int num1 = Integer.parseInt(sNum1);  
  10.             int num2 = Integer.parseInt(sNum2);  
  11.             //两个整数相除  
  12.             int ret = num1 / num2; //除数为0,出现异常  
  13.             System.out.println("结果=" + ret);  
  14.         } catch (ArithmeticException e) {  
  15.             System.out.println("除数为0");  
  16.         } catch (NumberFormatException e) {  
  17.             System.out.println("类型转换异常");  
  18.         } catch (Exception e) {  
  19.             e.printStackTrace(); //其他异常统一用父类接受也可以  
  20.         }  
  21.         System.out.println("end------");  
  22.     }  
  23. }  
或者直接用父类接收全部异常
[java]  view plain  copy
  1. public class ExceptionDemo1 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin----");  
  5.         String sNum1 = "10"//输入的除数  
  6.         String sNum2 = "0"//输入的被除数  
  7.         try {  
  8.             //String转换为int类型  
  9.             int num1 = Integer.parseInt(sNum1);  
  10.             int num2 = Integer.parseInt(sNum2);  
  11.             //两个整数相除  
  12.             int ret = num1 / num2; //除数为0,出现异常  
  13.             System.out.println("结果=" + ret);  
  14.         } catch (Exception e) {  
  15.             e.printStackTrace(); //直接用异常父类接收  
  16.         }  
  17.         System.out.println("end------");  
  18.     }  
  19. }  
注意:
1:一个catch语句,只能捕获一种类型的异常,如果需要捕获多种异常,就得使用多个catch语句.
2:代码在一瞬间只能出现一种类型的异常,只需要一个catch捕获,不可能同时出现多个异常.

4.finally代码块

finally语句块表示最终都会执行的代码,无论有没有异常.
---------------------------------------------------------------------------------------
什么时候的代码必须最终执行:
当我们在try语句块中打开了一些物理资源(磁盘文件/网络连接/数据库连接等),我们都得在使用完之后,最终关闭打开的资源.
---------------------------------------------------------------------------------------
finally的两种语法:
  1):try...finally: 此时没有catch来捕获异常,因为此时根据应用场景,我们会抛出异常,自己不处理.
  2):try...catch....finally:自身需要处理异常,最终还得关闭资源.

没有异常:
[java]  view plain  copy
  1. public class ExceptionDemo2 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin....");  
  5.         try {  
  6.             int ret = 10 / 2;  
  7.         } catch (ArithmeticException e) {  
  8.             System.out.println("异常:除数为0");  
  9.         } finally {  
  10.             System.out.println("关闭资源");  
  11.         }  
  12.         System.out.println("end.....");  
  13.     }  
  14. }  


出现异常:
[java]  view plain  copy
  1. public class ExceptionDemo2 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin....");  
  5.         try {  
  6.             int ret = 10 / 0;  
  7.         } catch (ArithmeticException e) {  
  8.             System.out.println("异常:除数为0");  
  9.         } finally {  
  10.             System.out.println("关闭资源");  
  11.         }  
  12.         System.out.println("end.....");  
  13.     }  
  14. }  


可以看见,没有异常或者出现异常之后,程序会处理异常,打印异常信息,然后会进入finally代码块执行代码块中的内容,无论有没有异常,finally中的代码都会执行.
注意:finally不能单独使用.
---------------------------------------------------------------------------------------
当只有在try或者catch中调用退出JVM的相关方法,此时finally才不会执行,否则finally永远会执行.
System.exit(0);//退出JVM
[java]  view plain  copy
  1. public  public class ExceptionDemo2 {  
  2.   
  3.     public static void main(String[] args) {  
  4.         System.out.println("begin....");  
  5.         try {  
  6.             int ret = 10 / 0;  
  7.         } catch (ArithmeticException e) {  
  8.             System.out.println("异常:除数为0");  
  9.             System.exit(0);//JVM退出  
  10.         } finally {  
  11.             System.out.println("关闭资源"); //此时不执行  
  12.         }  
相关文章
相关标签/搜索