zoukankan      html  css  js  c++  java
  • 2017.4.7 java异常处理总结

    目录

    1.java异常处理的几种错误做法
    2.异常处理示例
    3.常用异常
    4.异常类的继承关系
    5.异常处理机制
    6.Throw和Throws的区别
    7.e.toString(), e.getCause() , e.getMeage(), e.printStackTrace()

    1.java异常处理的几种错误做法

    http://blog.csdn.net/msyqmsyq/article/details/51504570

    (1)捕捉异常却不处理

    注意:调用一下printStackTrace算不上“处理异常”。因为调试阶段结束后,printStackTrace就不会再在异常处理模块负重要责任了。

    1  catch(Exception ex)  {
    2   ex.printStackTrace(); 
    3  }

    (2)不指定具体的异常,全部用Exception

    在catch语句中尽可能指定具体的异常类型,必要时使用多个catch。最后再使用Exception。

    1 try{
    2 //可能发生异常的代码块
    3 }catch(异常类名 e1){
    4 //处理代码
    5 }
    6 catch(异常类 e2){
    7 //处理代码
    8 }

    在JSE7中引入了新的语法:这样在该catch代码块中就用能够接受所有的在括号内部的异常类型的对象了。

    1 catch(异常类名 e1 | 异常类名 e2 | 异常类名e3 | ………)

    (3)占据资源不释放

    充分使用finally关键字,执行清理任务的代码。

    (4)不提供异常的详细信息

    printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程,但只提供了一些最基本的信息,未能说明实际导致错误的原因,同时也不易解读。因此,在出现异常时,最好能够提供一些文字信息,例如当前正在执行的类、方法和其他状态信息,包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。

    (5)try/catch 块太庞大

    把所有代码而不是可能出现异常的代码,都放入异常处理模块。原因是,不愿意去分析一大块代码中,哪几行可能会出现哪几种异常,因此就容易漏判。

    (6)输出数据不完整

    如果代码中间抛出了异常,前面执行的代码会不会有影响,后面输出的数据要不要做处理,都是要考虑的。对有些系统来说,数据不完整可能比系统停止带来的损失更大。

    比如可以这样处理:在for循环输出数据时,抛出了异常。可以向输出设备写一些信息,声明数据的不完整性;另一种可能有效的办法是,先缓冲要输出的数据,准备好全部数据之后再一次性输出。

    在JavaSE7中已经给出了带资源的try语句用来完成和finally相似的功能,即在try关键字后面带上参数。那么在try块中使用完这个文件流时,就不用使用finally块来将文件流关闭了,程序会自动的将这个文件流关闭,确保文件不被损坏,这样就提供了更加简单的方法来清理资源。

    1 tryInputSTream fis = new FileInputStream (source)){
    2 //可能发生异常的代码
    3 }catch{
    4 //处理代码
    5 }

    2.异常处理示例

    错误示例:

    1 OutputStreamWriter out = ...
    2 java.sql.Connection conn = ...
    3 try { 
    4  Statement stat = conn.createStatement();
    5  ResultSet rs = stat.executeQuery("select uid, name from user");
    7  while (rs.next())
    8  {
    9   out.println("ID:" + rs.getString("uid")",姓名:" + rs.getString("name"));
    11  }
    12  conn.close(); 
    13  out.close();
    14 }
    15 catch(Exception ex) {
    17  ex.printStackTrace(); 
    18 }

    按照上面的原则修改后:

     1 OutputStreamWriter out = ...
     2 java.sql.Connection conn = ...
     3 try {
     4  Statement stat = conn.createStatement();
     5  ResultSet rs = stat.executeQuery("select uid, name from user");
     7  while (rs.next()){
     9   out.println("ID:" + rs.getString("uid") + ",姓名: " + rs.getString("name"));
    10  }
    11 }
    12 catch(SQLException sqlex){//指定具体的异常14  out.println("警告:数据不完整");
    15  throw new ApplicationException("读取数据时出现SQL错误", sqlex); //处理异常或抛出新异常
    16 }
    17 catch(IOException ioex){//指定具体的异常
    19  throw new ApplicationException("写入数据时出现IO错误", ioex); //处理异常或抛出新异常
    20 }
    21 finally{ //释放资源
    23  if (conn != null) {
    24   try {
    25    conn.close();
    26   }
    27   catch(SQLException sqlex2){ //异常导致中断后,做的处理
    29    System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: " + sqlex2.toString());
    30   }
    31  }
    32 
    33  if (out != null) {
    34   try {
    35    out.close();
    36   }
    37   catch(IOException ioex2){ //异常导致中断后,做的处理
    39    System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString());
    40   }
    41  }
    42 }

    3.常用异常

    空指针异常 NullPointerExption 类型强制转换异常 ClassCastException
    数组负下标异常 NegativeArrayException 数组下标越界异常 ArrayIndexOutOfBoundsException
    文件未找到异常 FileNotFoundException 输入输出异常 IOException
    字符串转换为数字异常 NumberFormatException NumberFormatException SQLException
    运行时异常 RuntimeException 解析JSON异常 JSONException
      UnknownSessionException   ExpiredSessionException
    插入重复数据异常
    DuplicateKeyException
    文件已结束异常 EOFException

    4.异常类的继承关系

    http://blog.csdn.net/hguisu/article/details/6155636

    注意:异常分为受检类型和非受检类型。

    1 受检类型:继承了Exception但是不继承RuntimeException的子类。
    在程序编译期间就会检查,如果发现存在受检异常,那么程序根本就不能执行。不论是用catch还是用throws抛向上一级的catch,该异常必须进行处理2
    非受检类型Error,和继承RuntimeException的子类
    在执行期间才会发现异常并中断,在编译阶段不会检查。

    比如下面这段代码中,存在两个异常,IOException(受检)和NumberFormatException(非受检)。

    1 去掉IOException,无法通过编译。但是去掉NumberFormatException,可以通过编译。
    2 执行时,如果str无法转换成int,也还是会抛出异常。如果没有catch或者抛向上级的catch,运行阶段(非调试阶段)会造成无提示无处理的程序中断。
    1 public void read() throws IOException, NumberFormatException{
    2     String str;
    3     while(str==reader.readLine()!=null){
    4         int n = Integer.parseInt(str);
    5         System.out.println(n);
    6     }
    7 }    

    5.异常处理机制

    两种方式:catch并处理,或者抛向上级的catch。这里重点讲解抛向上级的catch。

    当方法抛出异常列表的异常时,方法将不对这些类型及其子类类型的异常作处理,而抛向调用该方法的方法,由他去处理

     1     import java.lang.Exception;  
     2     public class TestException {  
     3         static void pop() throws NegativeArraySizeException {  
     4             // 定义方法并抛出NegativeArraySizeException异常  
     5             int[] arr = new int[-3]; // 创建数组  
     6         }  
     7       
     8         public static void main(String[] args) { // 主方法  
     9             try { // try语句处理异常信息  
    10                 pop(); // 调用pop()方法  
    11             } catch (NegativeArraySizeException e) {  
    12                 System.out.println("pop()方法抛出的异常");// 输出异常信息  
    13             }  
    14         }  
    15       
    16     }  

    6.Throw和Throws的区别

    1 throw出现在方法内部,用于抛出异常2 throws出现在方法上,用于声明异常
    3 如果通过throw抛出了异常(2),并且这个异常是检查异常,则方法名上也必须用throws来声明方法可能会这个异常(1)
    4 程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块(3)
     1     package Test;  
     2     import java.lang.Exception;  
     3     public class TestException {  
     4         static int quotient(int x, int y) throws MyException { // 定义方法抛出异常  (1)
     5             if (y < 0) { // 判断参数是否小于0  
     6                 throw new MyException("除数不能是负数"); // 异常信息  (2)
     7             }  
     8             return x/y; // 返回值  
     9         }  
    10         public static void main(String args[]) { // 主方法  
    11             int  a =3;  
    12             int  b =0;   
    13             try { // try语句包含可能发生异常的语句  
    14                 int result = quotient(a, b); // 调用方法quotient()  
    15             } catch (MyException e) { // 处理自定义异常              (3)
    16                 System.out.println(e.getMessage()); // 输出异常信息  
    17             } catch (ArithmeticException e) { // 处理ArithmeticException异常  
    18                 System.out.println("除数不能为0"); // 输出提示信息  
    19             } catch (Exception e) { // 处理其他异常  
    20                 System.out.println("程序发生了其他的异常"); // 输出提示信息  
    21             }  
    22         }  
    23       
    24     }  
    25     class MyException extends Exception { // 创建自定义异常类  
    26         String message; // 定义String类型变量  
    27         public MyException(String ErrorMessagr) { // 父类方法  
    28             message = ErrorMessagr;  
    29         }  
    30       
    31         public String getMessage() { // 覆盖getMessage()方法  
    32             return message;  
    33         }  
    34     }  

    7.  e.toString(), e.getCause() , e.getMeage(), e.printStackTrace()

    2017.4.7 e.toString() 与 e.getMessage()的区别

    1 e.toString() : 异常的类型及信息,比如java.lang.ArithmeticException: / by zero
    2 e.getMessage() : 异常的信息, 比如/ by zero
    3 e.getCause() : 异常的原因,如果cause不存在或未知,返回null。
    4 e.printStackTrace() : 异常的跟踪栈。在运行阶段(非调试阶段)没有帮助。

     

  • 相关阅读:
    L1-045 宇宙无敌大招呼 (5分)
    L1-044 稳赢 (15分)
    L1-043 阅览室 (20分)
    L1-042 日期格式化 (5分)
    L1-041 寻找250 (10分)
    L1-040 最佳情侣身高差 (10分)
    L1-039 古风排版 (20分)
    L1-038 新世界 (5分)
    L1-037 A除以B (10分)
    利用C一种最有效的文件存储方式——16bit有符号位2进制存储
  • 原文地址:https://www.cnblogs.com/lyh421/p/6678005.html
Copyright © 2011-2022 走看看