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() : 异常的跟踪栈。在运行阶段(非调试阶段)没有帮助。

 

posted @ 2017-04-07 14:37  七月流火嗞嗞嗞  阅读(880)  评论(0编辑  收藏  举报