前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

Enum

作者头像
晚上没宵夜
发布2020-05-19 19:33:47
6610
发布2020-05-19 19:33:47
举报

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

1. Enum

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

1.1 先来看看Enum类源码

代码语言:java
复制
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 简单实例

代码语言:java
复制
public enum Animal {
    DOG, CAT, BIRD, LION, ELEPHANT;
}

1.3 简单实例的反编译源码

代码语言:java
复制
// 声明为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开始的有序数值

代码语言:java
复制
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);
    }

}
代码语言:java
复制
0:DOG
1:CAT
2:BIRD
3:LION
4:ELEPHANT

DOG
class enumm.EnumDemo$Animal
true

2. 自定义方法、变量

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

注意:

  • 若为枚举定义方法,那么必须先声明实例,且在最后一个实例后加分号
  • Java中不允许使用赋值符号 = 为枚举常量赋值,但可自定义方法来赋值
  • 父类方法只有toString没有被声明为final,那么只有toString才能被重写
代码语言:java
复制
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());
        }
    }
}
代码语言:java
复制
Animal{num=1, name='狗'}
Animal{num=2, name='猫'}
Animal{num=4, name='鸟'}
Animal{num=8, name='狮子'}
Animal{num=16, name='大象'}

3. 应用

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

代码语言:java
复制
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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-05-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. Enum
    • 1.1 先来看看Enum类源码
      • 1.2 简单实例
        • 1.3 简单实例的反编译源码
          • 1.4 常用方法
            • 1.5 简单使用
            • 2. 自定义方法、变量
            • 3. 应用
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档