Java之枚举(enum)--使用/教程/实例

Java之枚举(enum)--使用/教程/实例

原文网址: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类型是线程安全的。

相关推荐

2025年电子书十大品牌
www.bst365.com

2025年电子书十大品牌

📅 08-30 👁️ 7842
往美国寄快递用什么快递比较好 往美国邮寄快递最新攻略
Win11文本文档在哪里存放?如何快速找到?
www.bst365.com

Win11文本文档在哪里存放?如何快速找到?

📅 10-02 👁️ 7942