你的位置:首页 > Java教程

[Java教程]Java异常之自定义异常


哎呀,妈呀,又出异常了!俗话说:“代码虐我千百遍,我待代码如初恋”。

小Alan最近一直在忙着工作,已经很久没有写写东西来加深自己的理解了,今天来跟大家聊聊Java异常。Java异常的体系什么的,理论知识啥的我就懒得去BB太多了,是个搞Java开发的都知道,只是可能理解的不深,这个大家可以自己多看看资料,我就简单的说说。

什么是异常?

我不知道大家都是怎么去理解的,我的理解很简单,那就是不正常的情况,比如我现在是个男的,但是我却有着女人所独有的东西,在我看来这尼玛肯定是种异常,简直不能忍。就拿上面的异常图片来说,你应该是有小弟弟的,但你却没有小弟弟,这就是不正常的情况了,所以Java这个妹子会告诉你,你应该有小弟弟的才能办事,或者你没小弟弟就别来办事,你没小弟弟也要强上别人,那也没法玩啊是吧?

常说我们人的祖宗是猿,异常Exception的祖宗那就是Throwable类了,除了Exception类外,Throwable还有一个子类Error 。Error这玩意就不说了,你如果遇到了它你可以把电脑砸了,呼呼呼...跟大家开个玩笑,反正这玩意不是我们程序能处理的,它在程序处理的范畴之外。至于异常Exception又分为傻傻啥的,我就不BB了,再BB就B到这上面了。

给大家随便列举几个异常:

RuntimeException:你不能跑得足够快,可能因为你太胖了。关掉你的电脑,出门锻炼吧。

NullPointerException:你没有狗。请你先找一只狗,比如一只布烈塔尼獵犬,然后再试一次。

IndexOutOfBoundsException:你把食指放在了无法接收的地方,重新放置,再试一次。

FileNotFoundException:一名木匠应该总是知道他的工具放在哪里。

NotSerializableException:你正试图把一部电影改成电视剧。

这尼玛什么鬼?反正我是没看懂。还好今天我要理解的对象不是上面的这些玩意,搞错对象就不好了,看看就好了,但是别乱搞,男人都懂的,啧..啧..啧...。

 

自定义异常

今天我们要来理解的是什么是自定义异常,为什么要使用自定义异常,使用自定义异常有哪些好处,有哪些不好的地方?

要使用自定义异常就跟你和女朋友相处一样的,首先你得知道你为什么要跟你女朋友在一起,你女朋友有哪些好处,有哪些不好的地方,再来和你女朋友谈婚论嫁过一辈子,我们就先来说说这些问题,最后再来看怎么使用自定义异常,自定义异常的实现和使用非常简单,关键还是理解why的内容。

 

为什么要使用自定义异常,有什么好处?

1.我们在工作的时候,项目是分模块或者分功能开发的 ,基本不会你一个人开发一整个项目,使用自定义异常类就统一了对外异常展示的方式。

2.有时候我们遇到某些校验或者问题时,需要直接结束掉当前的请求,这时便可以通过抛出自定义异常来结束,如果你项目中使用了SpringMVC比较新的版本的话有控制器增强,可以通过@ControllerAdvice注解写一个控制器增强类来拦截自定义的异常并响应给前端相应的信息(关于springMVC控制器增强的知识有空再和大家分享)。

3.自定义异常可以在我们项目中某些特殊的业务逻辑时抛出异常,比如"中性".equals(sex),性别等于中性时我们要抛出异常,而Java是不会有这种异常的。系统中有些错误是符合Java语法的,但不符合我们项目的业务逻辑。

4.使用自定义异常继承相关的异常来抛出处理后的异常信息可以隐藏底层的异常,这样更安全,异常信息也更加的直观。自定义异常可以抛出我们自己想要抛出的信息,可以通过抛出的信息区分异常发生的位置,根据异常名我们就可以知道哪里有异常,根据异常提示信息进行程序修改。比如空指针异常NullPointException,我们可以抛出信息为“xxx为空”定位异常位置,而不用输出堆栈信息。

 

说完了为什么要使用自定义异常,有什么好处,我们再来看看自定义异常的毛病:

毋庸置疑,我们不可能期待JVM(Java虚拟机)自动抛出一个自定义异常,也不能够期待JVM会自动处理一个自定义异常。发现异常、抛出异常以及处理异常的工作必须靠编程人员在代码中利用异常处理机制自己完成。这样就相应的增加了一些开发成本和工作量,所以项目没必要的话,也不一定非得要用上自定义异常,要能够自己去权衡。

 

最后,我们来看看怎么使用自定义异常:

在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。

  • 所有异常都必须是 Throwable 的子类。
  • 如果希望写一个检查性异常类,则需要继承 Exception 类。
  • 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。

可以像下面这样定义自己的异常类:

class MyException extends Exception{ }

 

我们来看一个完整的实例:

 1 package com.czgo.exception; 2  3 /** 4  * 自定义异常类(继承运行时异常) 5  * @author AlanLee 6  * @version 2016/11/26 7 */ 8 public class MyException extends RuntimeException { 9  10   private static final long serialVersionUID = 1L; 11  12   /** 13    * 错误编码 14   */ 15   private String errorCode; 16  17   /** 18    * 消息是否为属性文件中的Key 19   */ 20   private boolean propertiesKey = true; 21  22   /** 23    * 构造一个基本异常. 24    * 25    * @param message 26    *      信息描述 27   */ 28   public MyException(String message) 29   { 30     super(message); 31   } 32  33   /** 34    * 构造一个基本异常. 35    * 36    * @param errorCode 37    *      错误编码 38    * @param message 39    *      信息描述 40   */ 41   public MyException(String errorCode, String message) 42   { 43     this(errorCode, message, true); 44   } 45  46   /** 47    * 构造一个基本异常. 48    * 49    * @param errorCode 50    *      错误编码 51    * @param message 52    *      信息描述 53   */ 54   public MyException(String errorCode, String message, Throwable cause) 55   { 56     this(errorCode, message, cause, true); 57   } 58  59   /** 60    * 构造一个基本异常. 61    * 62    * @param errorCode 63    *      错误编码 64    * @param message 65    *      信息描述 66    * @param propertiesKey 67    *      消息是否为属性文件中的Key 68   */ 69   public MyException(String errorCode, String message, boolean propertiesKey) 70   { 71     super(message); 72     this.setErrorCode(errorCode); 73     this.setPropertiesKey(propertiesKey); 74   } 75  76   /** 77    * 构造一个基本异常. 78    * 79    * @param errorCode 80    *      错误编码 81    * @param message 82    *      信息描述 83   */ 84   public MyException(String errorCode, String message, Throwable cause, boolean propertiesKey) 85   { 86     super(message, cause); 87     this.setErrorCode(errorCode); 88     this.setPropertiesKey(propertiesKey); 89   } 90  91   /** 92    * 构造一个基本异常. 93    * 94    * @param message 95    *      信息描述 96    * @param cause 97    *      根异常类(可以存入任何异常) 98   */ 99   public MyException(String message, Throwable cause)100   {101     super(message, cause);102   }103   104   public String getErrorCode()105   {106     return errorCode;107   }108 109   public void setErrorCode(String errorCode)110   {111     this.errorCode = errorCode;112   }113 114   public boolean isPropertiesKey()115   {116     return propertiesKey;117   }118 119   public void setPropertiesKey(boolean propertiesKey)120   {121     this.propertiesKey = propertiesKey;122   }123   124 }

使用自定义异常抛出异常信息:

 1 package com.czgo.exception; 2  3 public class MyExceptionTest { 4  5   public static void main(String[] args) { 6      7     String[] sexs = {"男性","女性","中性"}; 8     for(int i = 0; i < sexs.length; i++){ 9       if("中性".equals(sexs[i])){10         throw new MyException("你全家都是中性!");11       }else{12          System.out.println(sexs[i]);13        }14      } 15   }16 }

运行结果:

就是这么简单,我的话实现了很多构造函数,可以根据实际业务需求去抛出相应的自定义异常。

 

结束语:现在搞软件开发的人越来越多了,高手数不胜数,菜鸟也数不胜数,把这行的行情搅的比较混乱。所以初入这行的哥们一定要有危机意识。公司都想要工资开的不高,又能做一大把事情的人,搞开发很累,但是在当前的环境下,一定要不断的去提高自己。到了洗牌的时候,可能被淘汰的人里面就有你,除非你去做别的,不然就硬着头皮干几年把技术搞扎实,该复习的知识就多多复习,该学习的知识就多多学习,基础扎实了就去看看底层的东西,比如理解理解Java虚拟机,研究研究Spring源码。多关注关注前沿技术的发展,因为你现在所用的东西或许某一天大部分公司就不用了,或者根本满足不了项目的需求,这都是有可能的。希望大家都能混出自己的一片天地,小Alan现在也还在吃土中,所以大家都在一起前行,这世界终究是属于年轻人的,别气馁。