8-枚举+异常

 枚举

        枚举也是数据类型:引用类型

        在程序中需要定义一些明确的值:春天,夏天,秋天,冬天,使用枚举来完成

/*
 * 1.7之前没办法通过switch 来判断字符串,可以使用枚举和switch搭配来完成,
 * 1.7之后支持使用String类型来进行匹配,所以枚举的一些工作被String代替
 * 
 * 语法:
 * 访问权限修饰符 enum 枚举名{
 * 		具体的值(枚举常量)
 * }
 * 若有多个常量存在使用逗号隔开,在没有常量的后面还有其他实现,需要在其后面添加分号,否则可以不添加
 */
public enum WeekDay {
	
	MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
	/*
	 * 枚举的特点:
	 * 	1.所有定义的枚举,底层实现都是一个类,这个类继承了所有枚举的父类Enum(不能被显式地继承)
	 * 	2.枚举中是可以定义成员方法和抽象方法,成员变量的
	 * 	3.每个枚举值都是一个静态常量
	 * 	4.通过反编译可以看到枚举有一个隐藏的方法values 可以获取所有的枚举值
	 */
}


import java.util.Random;
public class EnumDemo {
	
	public static WeekDay getWeekDay(){
		int num = new Random().nextInt(7)+1;
		switch (num) {
		case 1:
			//枚举只能存储自身所定义的值,不能是其他值
			//获取枚举值:枚举名.常量名
			return WeekDay.MONDAY;
		case 2:
			return WeekDay.THURSDAY;
		case 3:
			return WeekDay.WEDNESDAY;
		case 4:
			return WeekDay.THURSDAY;
		case 5:
			return WeekDay.FRIDAY;
		case 6:
			return WeekDay.SATURDAY;
		case 7:
			return WeekDay.SUNDAY;
		default:
			return WeekDay.MONDAY;
		}
	}
	
	public static void main(String[] args) {
		//创建枚举对象
		WeekDay weekDay = getWeekDay();
		switch (weekDay) {
		case MONDAY:
			System.out.println("星期一");
			break;
		case TUESDAY:
			System.out.println("星期二");
			break;
		case WEDNESDAY:
			System.out.println("星期三");
			break;
		case THURSDAY:
			System.out.println("星期四");
			break;
		case FRIDAY:
			System.out.println("星期五");
			break;
		case SATURDAY:
			System.out.println("星期六");
			break;
		case SUNDAY:
			System.out.println("星期日");
			break;
		default:
			break;
		}
	}
}
  • 枚举扩展:

枚举的底层实现_头秃人强的博客-CSDN博客

        枚举在底层就是一个类,所以可以在枚举中定义属性方法:

@Getter
@ToString
public enum WeekDay {

    MONDAY("0000", "MONDAY", "星期一"){
        //无效代码
        public void method1(){
            System.out.println("enum WeekDay MONDAY.clazz method");
        }
    },
    TUESDAY("0001", "TUESDAY", "星期二"){
        //重写
        public void method(){
            System.out.println("enum WeekDay TUESDAY.clazz method");
        }
    };//WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;

    @Setter
    private String code;
    private String tag;
    private String message;

    //默认private
    WeekDay(String code, String tag, String message) {
        this.code = code;
        this.tag = tag;
        this.message = message;
    }

    public void method(){
        System.out.println("WeekDay.clazz method");
    }

    public static void main(String[] args) {
        //valueOf
        System.out.println(MONDAY.valueOf("MONDAY"));//WeekDay.MONDAY(code=0000, tag=MONDAY, message=星期一)
        System.out.println(TUESDAY.valueOf("MONDAY"));//WeekDay.MONDAY(code=0000, tag=MONDAY, message=星期一)
        //values
        System.out.println(Arrays.toString(MONDAY.values()));//[WeekDay.MONDAY(code=0000, tag=MONDAY, message=星期一), WeekDay.TUESDAY(code=0001, tag=TUESDAY, message=星期二)]

        //属性
        System.out.println(MONDAY.getCode());//0000
        System.out.println(MONDAY.getTag());//MONDAY
        System.out.println(MONDAY.getMessage());//星期一
        System.out.println(MONDAY);//WeekDay.MONDAY(code=0000, tag=MONDAY, message=星期一)

        //set get
        MONDAY.setCode("1111");
        System.out.println(MONDAY.getCode());//1111

        //方法
        MONDAY.method();//WeekDay.clazz method
//        MONDAY.method1();
        WeekDay.MONDAY.method();//WeekDay.clazz method
        TUESDAY.method();//enum WeekDay TUESDAY.clazz method
    }

}

  异常

/*
 * Throwable:所有异常的根类
 *         1.Error:一般指JVM出现了一些不可修复的问题,如:内存溢出,系统崩溃
 *             Error是由JVM抛出来的,此类错误名字的最后一定有Error
 *             Error级别的错误,我们不处理(处理不了)
 *         2.Exception:指程序中出现了不正常的情况,该问题可以被修复,名字后定有Exception
 *             运行时异常 --> RuntimeException --> 程序在运行时出现的异常
 *             编译时异常 --> Exception --> 写代码的时候出现的异常
 *             特点:只要发生运行时异常,异常位置之后的的代码都不会执行
 *                       编译时异常会在书写代码时提示,编译时必须处理(不处理程序无法正常执行)
 *
 */

  • 捕获异常:
/*
 * 捕获异常:
 * 		try...catch        (多应对一种异常)
 * 		异常处理:记录日志/打印异常信息/继续抛出异常
 */
public class Exception {
	
	public static void main(String[] args) {
		int x = 9;
		int y = 0;
		int result = 0;
		
		try {
            //抓取异常 
			result = x/y;
            //不执行
			System.out.println(result);

		} catch (ArithmeticException e) {
			System.out.println("出现异常");
			/*
			 * 通过e来获取信息
			 * 这些方法
			 * getMessage() 获取异常的描述信息,发生异常原因
			 * toString() 获取异常的类型和异常信息的描述
			 * printStackTrace() 打印异常的跟踪栈信息并输出到控制台上
			 * 		不需要使用System.out.println();
			 * 在开发和测试阶段使用,在项目上线的时候,所有的方法都进行替换和删除
			 */
			System.out.println(e.getMessage());
			System.out.println(e.toString());
			e.printStackTrace();
		}
		System.out.println("end......");
	}

}

        运行结果:

  •   多异常抓取:
/*
 * try...catch...catch 多异常抓取
 * catch的个数不限,有多少抓多少
 * 父类异常一定要放到最后一个catch中,不能放到最上面
 */
public class Demo {
	public static void main(String[] args) {
		System.out.println("begin.......");
		int x = 9;
		int y = 0;
		String str = "123a";
		int result = 0;
		try {
			int num = Integer.parseInt(str);
			result = x/y;
			System.out.println(result);
			System.out.println(num);
		}catch(ArithmeticException e) {
			System.out.println(e.getMessage());
		}catch(NumberFormatException e) {
			System.out.println(e.toString());
		}
			System.out.println("end.......");
	}

}

        运行结果:

  • 平行抓取:

/*
 * 能不使用Exception抓取所有异常就不使用,实在不能确定异常类型时再使用
 *
 * JDK1.7提供的平行抓取:
 *         通过 | 这个运算符来区分不同的异常
 *         但是若这样抓取需要将父类异常放到子类异常之后
 */

                try {
			int num = Integer.parseInt(str);
			result = x/y;
			System.out.println(result);
			System.out.println(num);
		}catch(ArithmeticException | NumberFormatException e) {
			System.out.println(e.getMessage());
		}
  • try...catch...finally:

/*
 * try...catch...finally
 *         finally关键字:finally代码块
 *         ps:finally代码块无论异常发生与否,都会执行
 *         一般作为释放资源用:IO,网络连接,数据库连接等,使用完之后需要释放资源
 *
 * 有一种扩展语句:try...finally
 *         抛出异常不处理,finally用来进行资源释放
 */

        当异常对象是Exception类(或其子类)的实例时,能通过Java虚拟机(无论是编译时异常还是运行时异常)或者throw语句抛出该异常对象,并能通过try...catch...finally处理

public class ExceptionTest {
    public static int result1() {
        int x = 9;
        int y = 0;
        int result = 0;
        try {
            result = x / y;
            return result;
        } catch (ArithmeticException e) {
            return Integer.MAX_VALUE;
        } finally {
            System.out.println("先赋值再运算" + result++);
            System.out.println(++result + "先运算再赋值");
            System.out.println("finally语句块被执行了");
        }
    }

    public static int result2() {
        int x = 9;
        int y = 3;
        int result = 0;

        try {
            result = x / y;
            return result;
        } catch (ArithmeticException e) {
            return Integer.MAX_VALUE;
        } finally {
            System.out.println("先赋值再运算" + result++);
            System.out.println(++result + "先运算再赋值");
            System.out.println("finally语句块被执行了");
        }
    }

    public static int result3() {
        try {
            return 1;
        } finally {
            //如果finally中有return语句,永远返回finally中的结果
            //此处有警告
            return 100;
        }
    }

    public static int result4() {
        try {
            return 1;
        } catch (java.lang.Exception e) {
            return 3;
        } finally {
            //如果finally中有return语句,永远返回finally中的结果
            //此处有警告
            return 100;
        }
    }

    public static void main(String[] args) {
        System.out.println(Integer.MAX_VALUE);
        System.out.println("------------------------");
        System.out.println(result1());

        System.out.println("------------------------");
        System.out.println(result2());

        System.out.println("------------------------");
        System.out.println(result3());

        System.out.println("------------------------");
        System.out.println(result4());
    }

}

        运行结果:

  • throw:

        能抓就别抛

/*
 * 	throw:创建一个异常并抛出,在方法体中进行异常抛出
 * 		语法:throw new 异常类("异常信息")
 * 		在方法中使用等价于return 终止方法
 * 	throw既可以抛出编译时异常,也可以抛出运行时异常
 * 		若抛出的是编译时异常,一般要再加throws,或者try...catch
 */
public class ExceptionTest {

    public static void main(String[] args) {
        String value = "123a";
        System.out.println("start\n");

        //运行时异常
        //不处理
//        int num = getNumber(value);
        /*
        Exception in thread "main" java.lang.NumberFormatException: 您输入的字符串不合法:123a
	    at demo.ExceptionTest.getNumber(ExceptionTest.java:30)
	    at demo.ExceptionTest.main(ExceptionTest.java:12)
         */
        //处理
        try {
            int num1 = getNumber(value);
        } catch (NumberFormatException e) {
            System.out.println(e.getMessage());
        }

        //编译时异常
        //必须处理
        try {
            int num2 = getNumberNeedDeel(value);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        //不必须处理
        int num3 = getNumberSelfDeel(value);

        System.out.println("\nend");
    }

    //抛出运行时异常
    public static int getNumber(String value) {
        try {
            return new Integer(value).intValue();
        } catch (NumberFormatException e) {
            //此处打印无效,因为有返回值,所以需要返回一个异常对象
            throw new NumberFormatException("您输入的字符串不合法:" + value);
            //JDK1.7增强了throw,在不创建异常对象的前提下抛出异常
//			throw e;
        }
    }

    //抛出编译时异常
    public static int getNumberNeedDeel(String value) throws Exception {
        try {
            return new Integer(value).intValue();
        } catch (NumberFormatException e) {
            throw new Exception("您输入的字符串不合法:" + value);//此处为编译时异常时要么throws要么try catch
        }
    }

    //自处理编译时异常
    public static int getNumberSelfDeel(String value) {
        try {
            try {
                return new Integer(value).intValue();
            } catch (NumberFormatException e) {
                throw new Exception("您输入的字符串不合法:" + value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

}

        运行结果:

  •   throws:
/*
 * throws:
 * 		作用在方法上,若方法有异常发生,此时可以使用throws关键字将方法中出现异常抛出处理
 * 
 * 在设计方法时,方法中会产生一些异常,但是这样写异常不应该在方法中处理而是需要在调用者来处理,
 * 		此时可以将当前方法中的异常抛出
 * ps: throws可以无限的向上抛出,但是终点main中还抛出--> 直接就是JVM
 * 若将所有异常都是用throws抛出,那么我们程序猿就失去作用
 */
public class Demo {
	public static void main(String[] args) {
		String value = "123a";
		int num = getNumber(value);
	}

	public static int getNumber(String value)throws NumberFormatException{
		return new Integer(value).intValue();
	}
}
  • throw和throws:

        throw:运用在方法体内部,给调用者返回一个异常对象,和return一样可以结束方法

        throws:运用于方法之上,表示当前方法异常不处理,提醒调用该方法者有异常未处理

        若使用 throw 抛出是Exception类型异常(编译时异常),必须在方法上使用throws将异常抛出提示调用者

        try-catch:发生异常时进入catch直接处理,处理后程序继续向下执行本方法代码

        throws / try-finally:主要起提示作用,强制本方法调用者进行异常处理,发生异常时此方法内位于异常后代码不再执行,异常直接抛给调用本方法的上层进入上层编写的catch中处理

        try-catch + throw-new-Exception() + (throws):发生异常时进入catch处理,处理后将创建的自定义异常抛给上层,方法内位于异常后代码编译时直接报unreachable;可用来做异常链;若throw的为编译时异常,方法签名也必须加上throws强制调用者处理异常,否则java会编译不通过,若为运行时异常,java不会强制写throws

  • 自定义异常:

        Java中提供非常丰富的异常类库,但是在某些时刻我们自己编译的代码中出现的问题,想使用异常进行提示,但是系统中的异常类库没有相似的,所以可以使用自定义异常来代替

        若自定义异常带提示作用,在写代码时(编译时)就提示作者,那么自定异常就需要继承Exception

        若自定异常只有运行时才会出现提示,那么自定义异常就需要继承RuntimeException

        无论是继承谁实现都是相同的

/*
 * 需求:定制一个桌子,桌子的半径[30.123~31.123]之间是合格的,否则提示不合格
 */
public class Demo {
	public static void main(String[] args) {
		Worker worker = new Worker("小明");
		Desk desk = new Desk(32.14);
		try {
			checkDesk(desk);
		} catch (DeskException e) {
			System.out.println(e.getMessage());
		}
	}
	public static void checkDesk(Desk desk) {
		double r = desk.getR();
		if(r >= 30.123 && r <= 31.123) {
			System.out.println("合格");
		}else {
			throw new DeskException("制作不合格,不在规定范围内:"+r);
		}
	}
}
//工人类
class Worker{
	private String name;
	public Worker() {super();}
	public Worker(String name) {
		super();
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	//做桌子
	public Desk makeDesk(double r) {
		return new Desk(r);
	}
}
//桌子类
class Desk{
	private double r;
	public Desk() {super();}
	public Desk(double r) {
		super();
		this.r = r;
	}
	public double getR() {
		return r;
	}
	public void setR(double r) {
		this.r = r;
	}
}
//自定义异常类
class DeskException extends RuntimeException{
	private static final long serialVersionUID = 1L;

	public DeskException() {super();}
	public DeskException(String message, Throwable cause,
                 boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}
	public DeskException(String message, Throwable cause) {
		super(message, cause);
	}
	public DeskException(String message) {
		super(message);
	}
	public DeskException(Throwable cause) {
		super(cause);
	}
}
  • 异常链和异常转换:

        异常链:把原始异常包装为异常类,从而形成一个多异常的排序序列,有助于查找异常发生的根本原因

        异常转换:当前最上层的系统是不关心底层的异常细节时,可以将原有的异常进行包装,将他输出给上一层异常

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,您想了解关于使用 @ExceptionHandler + @ControllerAdvice +枚举实现全局异常统一处理的内容,这是一个常用的方案,可以实现全局异常的捕获和处理,让程序更加健壮和稳定。 @ExceptionHandler注解用于标记一个方法,该方法用于处理指定的异常类型。@ControllerAdvice注解用于标记一个类,该类用于处理全局异常枚举则可以用于定义异常类型,方便异常处理时的统一管理。 在实现全局异常处理时,我们可以通过 @ExceptionHandler 注解来捕获指定的异常类型,并在方法中进行相应的处理。@ControllerAdvice注解可以让我们在一个类中定义多个 @ExceptionHandler方法,用于处理不同类型的异常。同时,我们也可以使用枚举来定义不同的异常类型,方便管理和调用。 下面是一个简单的示例,演示如何使用 @ExceptionHandler + @ControllerAdvice +枚举实现全局异常统一处理: ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = BusinessException.class) @ResponseBody public ResultVO handleBusinessException(BusinessException e) { return ResultVO.error(e.getCode(), e.getMessage()); } } public enum ExceptionEnum { PARAMETER_ERROR(1001, "参数错误"), DATA_NOT_FOUND(1002, "数据不存在"), SYSTEM_ERROR(5000, "系统错误"); private final int code; private final String message; ExceptionEnum(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public String getMessage() { return message; } } public class BusinessException extends RuntimeException { private final int code; public BusinessException(int code, String message) { super(message); this.code = code; } public BusinessException(ExceptionEnum exceptionEnum) { super(exceptionEnum.getMessage()); this.code = exceptionEnum.getCode(); } public int getCode() { return code; } } ``` 在上面的示例中,GlobalExceptionHandler类标记了@ControllerAdvice注解,用于全局异常处理。其中,handleBusinessException方法用于处理BusinessException异常,返回一个ResultVO对象,其中包含错误码和错误信息。 BusinessException则是一个自定义的异常类,它包含一个code属性和一个message属性,用于表示异常的错误码和错误信息。同时,它还提供了一个构造方法,可以根据ExceptionEnum来构造一个BusinessException对象。 ExceptionEnum则是一个枚举类,包含了不同的异常类型,每个异常类型都有一个对应的错误码和错误信息。 在实际开发中,我们可以根据实际需求来定义不同的异常类型和错误码,以便更好地管理和调用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值