Java之枚举(enum)

您所在的位置:网站首页 java枚举状态码 Java之枚举(enum)

Java之枚举(enum)

2024-07-14 07:19| 来源: 网络整理| 查看: 265

原文网址:Java之枚举(enum)--使用/教程/实例_IT利刃出鞘的博客-CSDN博客

简介

说明

本文用示例介绍Java中的枚举(enum)的用法。

使用场景

定义常量、状态机等。

枚举与常量类

常量类

以往设置常量,通常将常量放置在接口中,这样在程序中就可以直接使用了,并且该常量不能被修改,因为在接口中定义的常量时,该常量的修饰符为final与static。如:

public interface IConstants{ public static final int RED = 1; public static final int BLUE = 2; public static final int GREEN = 3; }

枚举与常量类的对比

项枚举类常量类单例

完全单例、线程安全。

枚举类编译后类为:public final class T extends Enum,不允许继承可防止被子类修改。

不单例

常量类可被继承修改、增加字段等,容易导致父类的不兼容。

性能

性能高。

常量值地址唯一,可以用==直接对比

性能低

使用常量类时,往往得通过equals去判断两者是否相等。

引用类

不需重新编译引用类。

枚举类编译时,没有把常量值编译到代码里,即使常量的值发生变化,也不会影响引用常量的类。

需要重新编译引用类。

常量类编译时,是直接把常量的值编译到类的二进制代码里,常量的值在升级中变化后,需要重新编译引用常量的类,因为里面存的是旧值。

越界

不会越界。

编译期间限定类型,不允许发生越界的情况。

可能越界。

switch语句支持枚举型,当switch使用int、String类型时,由于值的不稳定性往往会有越界的现象,对于这个的处理往往只能通过if条件筛选以及default模块来处理。

枚举与普通类

差别不大。枚举也可以定义变量与方法:

package com.example.a; enum MyEnum{ FIRST("第一个"), SECOND("第二个"), ; private final String description; MyEnum(String description) { this.description = description; } public String getDescription() { return description; } private String lastName; public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } } public class Demo { public static void main(String[] args) { MyEnum.FIRST.setLastName("Tony"); System.out.println(MyEnum.FIRST.getLastName()); System.out.println(MyEnum.FIRST.getDescription()); } }

执行结果

Tony 第一个 枚举与数据库

枚举型可以直接与数据库打交道,我通常使用varchar类型存储,对应的是枚举项的名字。

在下边的例子中,如果某个类中的字段为:private PersonType type; 则其对应的数据库中的值为:"STUDENT"、"TEACHER"。

package com.example.a; public enum PersonType{ STUDENT("学生"), TEACHER("教师"), ; private final String description; PersonType(String description) { this.description = description; } public String getDesc() { return description; } } 基础示例 一个参数

实例 

package com.example.a; enum PayTypeEnum{ ALIPAY("支付宝"), WECHAT("微信"), UNION_PAY("银联"), ; //这个必须定义,且成员变量的类型及个数必须对应于上边枚举的定义 //枚举标识码(英文描述) private String description; //必须提供为私有的,防止外部new对象 PayTypeEnum(String description) { this.description = description; } public String getDescription() { return description; } } public class Demo { public static void main(String[] args){ for (PayTypeEnum value : PayTypeEnum.values()) { System.out.println("name:" + value.name() + "," + "description:" + value.getDescription()); // 下边这样写结果是一样的 // System.out.println("name:" + value.toString() + "," + "description:" + value.getDescription()); } } }

运行结果

name:ALIPAY,desc:支付宝 name:WECHAT,desc:微信 name:UNIONPAY,desc:银联 多个参数

实例 

package com.example.a; interface IEnum{ String getCode(); String getDescription(); } enum PayTypeEnum implements IEnum{ ALIPAY("ALIPAY", "支付宝"), WECHAT("WECHAT", "微信"), UNION_PAY("UNION_PAY", "银联"), ; //这个必须定义,且成员变量的类型及个数必须对应于上边枚举的定义 //枚举标识码(英文描述) private final String code; //枚举标识码(中文描述) private final String description; //必须提供,而且是私有的,防止外部new对象 PayTypeEnum(String code, String description) { this.code = code; this.description = description; } public static String getDescriptionByCode(String code){ for(PayTypeEnum value : PayTypeEnum.values()){ if(value.getCode().equals(code)){ return value.getDescription(); } } return null; } @Override public String getCode() { return this.code; } @Override public String getDescription() { return this.description; } } public class Demo { public static void main(String[] args){ System.out.println(PayTypeEnum.getDescriptionByCode(PayTypeEnum.ALIPAY.getCode())); System.out.println(PayTypeEnum.getDescriptionByCode(PayTypeEnum.WECHAT.getCode())); } }

运行结果

支付宝 微信 异常处理应用

异常码枚举

package enums.expection; import org.apache.commons.lang.StringUtils; public enum ErrorCodeEnum { SYS_ERROR(1001, "系统错误,请重试"), UNKNOWN_ERROR(1002, "未知的系统异常"), SERVICE_INVOKE_FAIL(1003, "服务调用失败"), ILLEGAL_ARGS(1004, "参数校验错误"), ; /** * 结果码值 */ private final Integer code; /** * 描述 */ private final String description; ErrorCodeEnum(Integer code, String description) { this.code = code; this.description = description; } public static ErrorCodeEnum getByValue(String code) { for (ErrorCodeEnum result : values()) { System.out.println(result.ordinal()); if (StringUtils.equals(result.getCode(), code)) { return result; } } return null; } public Integer getCode() { return code; } public String getDescription() { return description; } }

自定义异常

package enums.expection; import org.apache.commons.lang.StringUtils; import java.util.HashMap; import java.util.Map; public class WangException extends RuntimeException { /** 错误码枚举*/ private ErrorCodeEnum errorCode; /** * 详细错误信息 */ private Map errorMap = new HashMap(); /** * 带参构造器 */ public WangException(ErrorCodeEnum errorCode) { super(errorCode.getDesc()); this.setErrorCode(errorCode); } /** * 带参构造器. */ public WangException(ErrorCodeEnum errorCode, String message) { super(StringUtils.isNotBlank(message) ? message : errorCode.getDesc()); this.setErrorCode(errorCode); } /** * 带参构造器 */ public WangException(ErrorCodeEnum errorCode, Map errorMap) { this(errorCode); this.errorMap = errorMap; } /** * 带参构造器 */ public WangException(String message) { super(message); this.setErrorCode(ErrorCodeEnum.UNKNOWN_ERROR); } /** * Gets error code. */ public ErrorCodeEnum getErrorCode() { return errorCode; } /** * Sets error code. */ public void setErrorCode(ErrorCodeEnum errorCode) { this.errorCode = errorCode; } /** * Gets error map. */ public Map getErrorMap() { return errorMap; } /** * Sets error map. */ public void setErrorMap(Map errorMap) { this.errorMap = errorMap; } private static String findMessage(Map errorMap) { if (errorMap.isEmpty()) { return null; } return errorMap.values().iterator().next(); } }

测试类

package enums.expection; public class Test { public static void main(String[] args) { String name=""; int i=0; try { if (name == null) throw new WangException(ErrorCodeEnum.ILLEGAL_ARGS); if(i==0) throw new WangException(ErrorCodeEnum.ILLEGAL_ARGS, "参数不能为0"); }catch (WangException e){ e.printStackTrace(); System.out.println("异常码:"+e.getErrorCode().getCode()); System.out.println("异常描述:"+e.getMessage()); } } } 高级操作 接口中定义注解 package org.example.a; interface Color { enum Green {LIGHT_GREEN, DARK_GREEN} enum Red {LIGHT_RED, DARK_RED} } public class Demo { public static void main(String[] args) { System.out.println(Color.Green.DARK_GREEN.ordinal()); } }

执行结果

1 枚举上使用注解

见:Java--Annotation(注解)--使用/应用/实例_IT利刃出鞘的博客-CSDN博客

实现原理

枚举类

package org.example.a; public enum Season { SPRING, SUMMER, AUTUMN, WINTER; }

反编译代码

public final class Season extends Enum { private Season(String s, int i) { super(s, i); } public static Season[] values() { Season at[]; int i; Season at1[]; System.arraycopy(at = ENUM$VALUES, 0, at1 = new Season[i = at.length], 0, i); return at1; } public static Season valueOf(String s) { return (Season)Enum.valueOf(demo/Season, s); } public static final Season SPRING; public static final Season SUMMER; public static final Season AUTUMN; public static final Season WINTER; private static final Season ENUM$VALUES[]; static { SPRING = new Season("SPRING", 0); SUMMER = new Season("SUMMER", 1); AUTUMN = new Season("AUTUMN", 2); WINTER = new Season("WINTER", 3); ENUM$VALUES = (new Season[] { SPRING, SUMMER, AUTUMN, WINTER }); } }

分析

通过反编译后代码可见,该类继承了Enum类,同时final关键字表明这个类不能被继承。

字段都是static类型的,static类型的属性会在类被加载之后被初始化。当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的。所以,创建一个enum类型是线程安全的。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3