为什么要使用自定义异常,有什么好处?
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 }
运行结果:
就是这么简单,我的话实现了很多构造函数,可以根据实际业务需求去抛出相应的自定义异常。