当前位置: 首页 > >

Java异常类型体系概述与应用

发布时间:

Java异常体系概述

?自己对于Java异常体系的了解通过画图的方式画出来了,其中Checked异常通常指的是与程序自身的错误相关的,Unchecked异常通常是由于外界引起的,列入我们的数据库连接失败、所加载的文件不存在等。在我们使用自定义异常的时候,有一种设计方式好像是和枚举类型相结合的,在下面尝试对这种方式进行一个实现。



Java异常处理

系统抛出异常通常有三种形式:Throw、Throws、系统自己抛出。这些抛出的异常的处理通常我们是通过try-catch-finally的语句体来进行处理的。Throw与Throws都是消极的处理方式,因为他们并没有对异常进行一个有效的处理而是交给上层的函数来处理,这只是一种处理的思路也并不是说这样的处理形式就不好。Throw抛出异常通常是用在方法体内部的,抛出一个具体的异常对象,而Throws一般是又在方法头中,表示有异常发生的可能,如果发生了则向上抛出异常。


    Throw抛出异常

    public class ExceptionTest {

    public static void main(String[] args) {
    int a =3;
    int [] arr = new int[3];
    System.out.println(findElementByIndex(a,arr));
    }

    public static int findElementByIndex(int index,int[] arr){
    if(index>=arr.length||index<0){
    throw new IndexOutOfBoundsException("在执行findElementByIndex方法的时候发生数组越界的错误");
    }else{
    return arr[index];
    }
    }

    }

    Throws抛出异常

    ?上述的findElementByIndex方法稍作改动即可:

    public static int findElementByIndex (int index,int[] arr)throws IndexOutOfBoundsException{
    return arr[index];
    }
    系统自己抛出异常

    异常的处理

在异常处理的try-catch-finally结构中try必须有,catch、finally至少必须要有一个,catch可以有多个,他是用来捕获异常的,如果有多个catch的话我们通常把小的小范围的异常放在靠*try的catch中,大的异常放在靠后的catch中因为异常的捕获是从上到下的,并且只会捕获一次,如果把Exception的异常放在了第一个catch中那么我们后面如果再放类如IndexOutOfBoundsException类较小的异常自然也就是没有什么意义了。我们在try中放的是正常的业务逻辑代码,当有异常发生时才会执行catch的代码,没有的话则就进行绕行;当try或是catch执行结束后必须执行finally的。


在进行异常处理的时候我们应该注意,如果一个方法被覆盖,那么覆盖他的方法必须抛出相同的异常或是说异常的子类;如果父类的方法中是抛出类多个异常那么重写的子类方法中必须抛出那些异常的子集,也就是说不能抛出新的异常。


?在Try语句体中存在异常:(try中异常后的语句体没有执行,但是执行了catch以及finally中的代码


public static void main(String[] args) {

try {
int a =5/0;
System.out.println("a is "+a);
}catch (Exception e){
e.printStackTrace();
}finally {
System.out.println("Phrase 3 is over");
}
}


在catch或finally中也存在异常:


当catch中的异常在处理语句之前发生的时候,在30行对try中异常的处理就不会执行,


try {
int a =5/0;
System.out.println("a is "+a);
}catch (Exception e){
int a = 5/0;//第29行
System.out.println("try的方法体中发生了异常");
}finally {
System.out.println("Phrase 3 is over");
}


?当catch中的异常发生在异常处理之后的时候,catch中的异常照常处理,先执行对try中异常的处理后又执行了finally中的方法,最后输出了catch中发生的异常


try {
int a =5/0;
System.out.println("a is "+a);
}catch (Exception e){
System.out.println("try的方法体中发生了异常");
int a = 5/0;//第30行
}finally {
System.out.println("Phrase 3 is over");
}


?在finally中发生异常时的情况,finally中方法不能正常执行:


try {
int a =5/0;
System.out.println("a is "+a);
}catch (Exception e){
System.out.println("try的方法体中发生了异常");
}finally {
int a = 5/0;//第22行
System.out.println("Phrase 3 is over");
}


在对catch或是finally中存在的与异常做了处理:


try {
int a =5/0;
System.out.println("a is "+a);
}catch (Exception e){
try{
System.out.println("对第一层try中放生的异常进行了第一步处理");
int a =5/0;
System.out.println("对第一层try中放生的异常进行了第二步处理");
}catch (Exception ex){
System.out.println("对catch中有的异常进行了处理");
}finally {
System.out.println("执行的是catch语句块中的finally中的代码");
}
}finally {
System.out.println("Phrase 3 is over");
}


Java自定义异常

public class MyException extends Exception {

private String returnCode;
private String returnMsg;

public MyException(){
super();
}

public MyException(String returnMsg){
super(returnMsg);
this.returnMsg = returnMsg;
}

public MyException(String returnMsg,String returnCode){
super();
this.returnMsg = returnMsg;
this.returnCode = returnCode;
}

public String getReturnCode() {
return returnCode;
}

public String getReturnMsg() {
return returnMsg;
}
}

public abstract class ExceptionTest {

public static void main(String[] args) {
try{
ExceptionTest.testException(-1);
}catch (MyException e){
e.printStackTrace();
System.out.println("returnCode: "+e.getReturnCode());
System.out.println("returnMsg: "+e.getReturnMsg());
}
}

public static void testException(int temp) throws MyException{
if(temp<0){
throw new MyException("The resion is myException","444");
}else {
System.out.println("testException方法成功执行");
}
}
}

?如果我们在主方法中执行ExceptionTest.testException(-1)的时候发不进行处理那么编译器将会报错,因为我们的MyException异常集成的是Exception属于Checked异常,如果将Exception换成RunTimeException的话就不会发生这样的错误。


结合枚举与自定义异常实现一个外部统一响应码:


在这里我们的实现出了在这篇博客提到的自定义异常先关的信息,还集合了枚举部分的知识,对于枚举部分不熟悉的朋友可以先去看看有关枚举部分的内容,这样的话更容易理解这一部分的内容:


枚举设置统一的响应码:


public enum ExceptionEnum {
NoExistUser("10001","用户不存在"),
LackAuthority("10002","权限不够"),
LinkOverTime("10003","连接超时");

private String returnCode;
private String returnMsg;

ExceptionEnum(String returnCode, String returnMsg) {
this.returnCode = returnCode;
this.returnMsg = returnMsg;
}

public String getReturnCode() {
return returnCode;
}

public String getReturnMsg() {
return returnMsg;
}

//用来判断,这一个错误码是否存在
public static ExceptionEnum statOf(String ecode) {
for (ExceptionEnum state : values()){
if (state.getReturnCode().equals(ecode)){
return state;
}
}
return null;
}
}

自定义异常基类:


public class BaseRunTimeException extends RuntimeException implements Serializable {
private static final long serialVersionUID = 1L;

private ExceptionEnum exceptionEnum;
private String detailMsg;

//带自定义异常信息异常模板构造方法
public BaseRunTimeException(ExceptionEnum exceptionEnum,String detailMsg){
this.detailMsg = detailMsg;
this.exceptionEnum = exceptionEnum;
}
//模板异常的构造方法
public BaseRunTimeException (ExceptionEnum exceptionEnum){
this.exceptionEnum = exceptionEnum;
}

public ExceptionEnum getExceptionEnum() {
return exceptionEnum;
}

public String getDetailMsg() {
return detailMsg;
}

public void setDetailMsg(String detailMsg) {
this.detailMsg = detailMsg;
}

@Override
public String toString() {
if (detailMsg!=null){
return "returnCode: " + exceptionEnum.getReturnCode() +
", returnMsg: " + detailMsg ;
}else{
return "returnCode: " + exceptionEnum.getReturnCode() +
", returnMsg: " + exceptionEnum.getReturnMsg();
}
}
}

?对于异常信息的的测试:


public abstract class ExceptionTest {

public static void main(String[] args) {
try{
dbConnection();
if(true){
throw new BaseRunTimeException(ExceptionEnum.NoExistUser);
}
if(false){
throw new BaseRunTimeException(ExceptionEnum.LackAuthority,"亲,你的访问权限不够呦");
}
}catch(BaseRunTimeException e){
e.printStackTrace();
System.out.println(e.toString());
}catch (Exception ex){
System.out.println("其他种类异常");
}
finally {
System.out.println("finally方法正确执行,资源得以完全关闭");
}

}

public static void dbConnection(){
try{
if(true){
throw new Exception("这里发生的是一个数据库连接的异常");
}
}catch (Exception e){
//对外不暴露异常信息,只显示模板异常
throw new BaseRunTimeException(ExceptionEnum.LinkOverTime,"自定义的数据库异常");
}
}

}

运行截图:




友情链接: 高中资料网 职业教育网 成人教育网 理学 大学工学资料