Enum

最近Github上项目中看到了用枚举来列举错误码,听就是听过枚举,但没实际用过,所以来学习下

1. Enum

Enum是一种受限制的类,编译时IDE会为enum生成一个相关的类,这个类继承自 java.lang.Enum,且具有自己的方法

1.1 先来看看Enum类源码

public abstract class Enum< E extends Enum<E> > implements Comparable<E>, Serializable {

    // 枚举实例的名字
    private final String name;
    public final String name() {
        return name;
    }

  	// 枚举声明的次序
    private final int ordinal;
    public final int ordinal() {
        return ordinal;
    }

    // 构造方法,只能编译器调用,说明枚举有名字和次序
    protected Enum(String name, int ordinal) {
        this.name = name;
        this.ordinal = ordinal;
    }

    // 应该调用这个来获取名字
    public String toString() {
        return name;
    }

    // 因为JVM会确保只有一个实例,所以可用==来比较
    public final boolean equals(Object other) {
        return this == other;
    }

    // 重写:比较的是声明次序
    public final int compareTo(E o) {
        Enum<?> other = (Enum<?>)o;
        Enum<E> self = this;
        if (self.getClass() != other.getClass() && // optimization
            self.getDeclaringClass() != other.getDeclaringClass())
            throw new ClassCastException();
        return self.ordinal - other.ordinal;
    }

    // 返回枚举实例的数组
    public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
        T result = enumType.enumConstantDirectory().get(name);
        if (result != null)
            return result;
        if (name == null)
            throw new NullPointerException("Name is null");
        throw new IllegalArgumentException(
            "No enum constant " + enumType.getCanonicalName() + "." + name);
    }
}

1.2 简单实例

public enum Animal {
    DOG, CAT, BIRD, LION, ELEPHANT;
}

1.3 简单实例的反编译源码

// 声明为final类
final class Animal extends Enum{
    
    // 编译器生成的两个方法:values、valueOf
    public static Animal[] values(){
        return (Animal[])$VALUES.clone();  // 克隆一个
    }
   
    public static Animal valueOf(String s){
        return (Animal)Enum.valueOf(com/howl/enumn/Animal, s);
    }
    
    // 私有构造方法
    private Animal(String s, int i){
        super(s, i);
    }
    
    // 我们写的变量,本质为实例变量
    public static final Animal DOG;
    public static final Animal CAT;
    public static final Animal BIRD;
    public static final Animal LION;
    public static final Animal ELEPHANT;
    private static final Animal $VALUES[];

    // 实例化
    static {    
        DOG = new Animal("DOG", 0);
        CAT = new Animal("CAT", 1);
        BIRD = new Animal("BIRD", 2);
        LION = new Animal("LION", 3);
        ELEPHANT = new Animal("ELEPHANT", 4);
        $VALUES = (new Animal[] {
            DOG, CAT, BIRD, LION, ELEPHANT
        });
    }
}

各实例会在静态代码块被赋值,根据JVM的加载过程,我们知道Enum的创建过程是线程安全的

至此大家应该对Enum有稍微的了解,那么再来看看枚举的常用方法

1.4 常用方法

返回值

方法名

解释

Enum[]

values()

返回enum实例数组

Enum

valueOf()

返回指定名字的enum实例

int

compareTo()

实现了该接口,可比较

int

ordinal()

返回声明次序

String

name()

返回实例名

Enum

getDeclaringClass()

返回enum类型

boolean

equals()

比较是否同一对象

  • JVM保证枚举类型仅一个常量实例,所以也可用 == 来比较enum实例

1.5 简单使用

如果枚举不添加任何方法,枚举值默认为从0开始的有序数值

public class EnumDemo {

    // 约定值大写,序号默认从0开始
    enum Animal {
        DOG, CAT, BIRD, LION, ELEPHANT;
    }

    public static void main(String[] args) {
        
        // 遍历枚举值
        for (Animal value : Animal.values()) {
            System.out.println(value.ordinal() + ":" + value);
        }

        // 其方法
        Animal dog = Animal.DOG;
        System.out.println(dog.name());
        System.out.println(dog.getDeclaringClass());
        System.out.println(Animal.valueOf("DOG") == dog);
    }

}
0:DOG
1:CAT
2:BIRD
3:LION
4:ELEPHANT

DOG
class enumm.EnumDemo$Animal
true

2. 自定义方法、变量

编译器会为枚举类自动继承Enum,所以无法再使用继承了,其余方面和普通类没什么区别

注意:

  • 若为枚举定义方法,那么必须先声明实例,且在最后一个实例后加分号
  • Java中不允许使用赋值符号 = 为枚举常量赋值,但可自定义方法来赋值
  • 父类方法只有toString没有被声明为final,那么只有toString才能被重写
public enum  Animal {

    // 声明实例
    DOG(1,"狗"),
    CAT(2,"猫"),
    BIRD(4,"鸟"),
    LION(8,"狮子"),
    ELEPHANT(16,"大象");

    // 私有属性
    private int num;
    private String name;
    
    // 获取内部私有属性的接口
    public int getNum() {
        return num;
    }
    public String getName() {
        return name;
    }
    
    // 构造方法只能声明为private,或者不声明
    private Animal(int num,String name){
        this.num = num;
        this.name = name;
    }

    // 可以重写toString来代替get属性的方法
    @Override
    public String toString() {
        return "Animal{" +
                "num=" + num +
                ", name='" + name + '\'' +
                '}';
    }

    // 静态方法
    public static void main(String[] args) {
        for (Animal value : Animal.values()){
            System.out.println(value.toString());
        }
    }
}
Animal{num=1, name='狗'}
Animal{num=2, name='猫'}
Animal{num=4, name='鸟'}
Animal{num=8, name='狮子'}
Animal{num=16, name='大象'}

3. 应用

枚举可以将常量组织起来,统一进行管理,而且安全性有保证,那么其常见于错误码的同一管理

public enum ErrorCodeEnum {

    SUCCESS(0000,"成功"),
    PARAM_TYPE_ERROR(1000,"参数类型错误"),
    USER_NOT_LOGIN(2000,"用户未登录"),
    SERVER_ERROR(3000,"服务端错误");

    private Integer code;
    private String msg;

    public Integer getCode(){
        return code;
    }
    public String getMsg(){
        return msg;
    }

    private ErrorCodeEnum(Integer code, String msg){
        this.code = code;
        this.msg = msg;
    }
}

参考

https://www.cnblogs.com/jingmoxukong/p/6098351.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Holder类

    这个类在 javax.xml.ws.Holder 中,笔者在很多地方都遇到过XXXHoler类,只知道包装了我们需要的值,但不知道为什么要包装多一层。其实Hol...

    Howl
  • 重写equals和hashCode方法

    Object类中定义了equal和hashCode方法,又因为Object是基类,所以继承了Object的类都有这两个方法

    Howl
  • Spring入门(二)——DI

    Dependency Injection,依赖注入。当对象里有属性或对象的时候,就需要为这些属性或对象赋值

    Howl
  • Spring MVC 参数的绑定方法

    在Spring MVC中,常见的应用场景就是给请求的Url绑定参数。本篇就介绍两种最最基本的绑定参数的方式: 基于@RequestParam 这种方法一般...

    用户1154259
  • 细说shiro之五:在spring框架中集成shiro

    特别地!Shiro使用了日志框架slf4j,因此需要对应配置指定的日志实现组件,如:log4j,logback等。 在此,以使用log4j为日志实现为例:

    2Simple
  • python列表、元组(三)

    py3study
  • Redis专题-常用命令的使用

    1. 查看所有键:keys *  //生产上客户端不建议直接使用keys * 来查询数数据,相当于MySQL的全表扫描,可以使用keys user*来缩小查询范...

    秋日芒草
  • 获取字段的元数据

    用户2657851
  • python global()函数

    promos = [globals()[name] for name in globals() if name.endswith('_promo') and n...

    用户5760343
  • Elasticsearch聚合学习之五:排序结果不准的问题分析

    版权声明:欢迎转载,请注明出处,谢谢。 https://blog.csdn.net/boling_...

    程序员欣宸

扫码关注云+社区

领取腾讯云代金券