自定义异常以及异常使用误区

一、自定义异常

      Java确实给我们提供了非常多的异常,但是异常体系是不可能预见所有的希望加以报告的错误,所以Java允许我们自定义异常来表现程序中可能会遇到的特定问题,总之就是一句话:我们不必拘泥于Java中已有的异常类型。

      Java自定义异常的使用要经历如下四个步骤:

      1、定义一个类继承Throwable或其子类。

      2、添加构造方法(当然也可以不用添加,使用默认构造方法)。

      3、在某个方法类抛出该异常。

      4、捕捉该异常。

[java]
  1. /** 自定义异常 继承Exception类 **/  
  2. public class MyException extends Exception{  
  3.     public MyException(){  
  4.           
  5.     }  
  6.       
  7.     public MyException(String message){  
  8.         super(message);  
  9.     }  
  10. }  
  11.   
  12. public class Test {  
  13.     public void display(int i) throws MyException{  
  14.         if(i == 0){  
  15.             throw new MyException("该值不能为0.......");  
  16.         }  
  17.         else{  
  18.             System.out.println( i / 2);  
  19.         }  
  20.     }  
  21.       
  22.     public static void main(String[] args) {  
  23.         Test test = new Test();  
  24.         try {  
  25.             test.display(0);  
  26.             System.out.println("---------------------");  
  27.         } catch (MyException e) {  
  28.             e.printStackTrace();  
  29.         }  
  30.     }  
  31. }  

      运行结果:

异常的使用误区

      首先我们先看如下示例:该实例能够反映java异常的不正确使用(其实这也是我刚刚学Java时写的代码)!!

[java]
  1. OutputStreamWriter out = null;  
  2.         java.sql.Connection conn = null;  
  3.         try {            //   ---------1  
  4.             Statement stat = conn.createStatement();  
  5.             ResultSet rs = stat.executeQuery("select *from user");  
  6.             while (rs.next()){  
  7.                 out.println("name:" + rs.getString("name") + "sex:"  
  8.                         + rs.getString("sex"));  
  9.             }  
  10.             conn.close();         //------2  
  11.             out.close();  
  12.         }   
  13.         catch (Exception ex){    //------3  
  14.             ex.printStackTrace();    //------4  
  15.         }  

      1、-----------1

      对于这个try…catch块,我想他的真正目的是捕获SQL的异常,但是这个try块是不是包含了太多的信息了。这是我们为了偷懒而养成的代码坏习惯。有些人喜欢将一大块的代码全部包含在一个try块里面,因为这样省事,反正有异常它就会抛出,而不愿意花时间来分析这个大代码块有那几块会产生异常,产生什么类型的异常,反正就是一篓子全部搞定。这就想我们出去旅游将所有的东西全部装进一个箱子里面,而不是分类来装,虽不知装进去容易,找出来难啊!!!所有对于一个异常块,我们应该仔细分清楚每块的抛出异常,因为一个大代码块有太多的地方会出现异常了。

      结论一:尽可能的减小try块!!!

      2、--------2

      在这里你发现了什么?异常改变了运行流程!!不错就是异常改变了程序运行流程。如果该程序发生了异常那么conn.close();out.close();是不可能执行得到的,这样势必会导致资源不能释放掉。所以如果程序用到了文件、Socket、JDBC连接之类的资源,即使遇到了异常,我们也要确保能够正确释放占用的资源。这里finally就有用武之地了:不管是否出现了异常,finally总是有机会运行的,所以finally用于释放资源是再适合不过了。

      结论二:保证所有资源都被正确释放。充分运用finally关键词。

      3、----------3

      对于这个代码我想大部分人都是这样处理的,(LZ也是尴尬)。使用这样代码的人都有这样一个心理,一个catch解决所有异常,这样是可以,但是不推荐!为什么!首先我们需要明白catch块所表示是它预期会出现何种异常,并且需要做何种处理,而使用Exception就表示他要处理所有的异常信息,但是这样做有什么意义呢?

      这里我们再来看看上面的程序实例,很显然它可能需要抛出两个异常信息,SQLException和IOException。所以一个catch处理两个截然不同的Exception明显的不合适。如果用两个catch,一个处理SQLException、一个处理IOException就好多了。所以:

      结论三:catch语句应当尽量指定具体的异常类型,而不应该指定涵盖范围太广的Exception类。 不要一个Exception试图处理所有可能出现的异常。

      4、----------4

      这个就问题多多了,我敢保证几乎所有的人都这么使用过。这里涉及到了两个问题,一是,捕获了异常不做处理,二是异常信息不够明确。

      4.1、捕获异常不做处理,就是我们所谓的丢弃异常。我们都知道异常意味着程序出现了不可预期的问题,程序它希望我们能够做出处理来拯救它,但是你呢?一句ex.printStackTrace()搞定,这是多么的不负责任对程序的异常情况不理不顾。虽然这样在调试可能会有一定的帮助,但是调试阶段结束后呢?不是一句ex.printStackTrace()就可以搞定所有的事情的!

      那么怎么改进呢?有四种选择:

      1、处理异常。对所发生的的异常进行一番处理,如修正错误、提醒。再次申明ex.printStackTrace()算不上已经“处理好了异常”.

      2、重新抛出异常。既然你认为你没有能力处理该异常,那么你就尽情向上抛吧!!!

      3、封装异常。这是LZ认为最好的处理方法,对异常信息进行分类,然后进行封装处理。

      4、不要捕获异常。

      4.2、异常信息不明确。我想对于这样的:java.io.FileNotFoundException: ………信息除了我们IT人没有几个人看得懂和想看吧!所以在出现异常后,我们最好能够提供一些文字信息,例如当前正在执行的类、方法和其他状态信息,包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。起码我公司是需要将异常信息所在的类、方法、何种异常都需要记录在日志文件中的。

所以:

      结论四:既然捕获了异常,就要对它进行适当的处理。不要捕获异常之后又把它丢弃,不予理睬。 不要做一个不负责的人。

      结论五:在异常处理模块中提供适量的错误原因信息,组织错误信息使其易于理解和阅读。

      对于异常还有以下几个注意地方:

      六、不要在finally块中处理返回值。

      七、不要在构造函数中抛出异常。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值