Java枚举

191 阅读2分钟

Java枚举的基本用法

用逗号隔开,不指定枚举的数值,使用的时候都是直接用。

在Print的时候会打印枚举的字面值。

public class UseEnum {
    public enum Sky {
        Sun, Earth, Moon
    }

    public enum Days {
        Monday, Tuesday;
    }

    public static void main(String[] args) {
        var x = Sky.Sun;
        System.out.println(x == Sky.Moon);//false
        System.out.println(x == Sky.Sun);//true
        System.out.println(x);//Sun
        System.out.println(Sky.valueOf("Sun"));//打印Sun
        System.out.println(Sky.valueOf("Sunnn"));//抛出异常
    }
}

枚举跟字符串的关系比较紧密,可以跟字符串进行互转。但是Sky.valueOf(s)必须保证s确实存在,否则抛出异常。

自定义枚举的值

使用括号,可以给枚举对象设置构造函数,这样就可以给枚举添加一些额外信息

public class UseEnum {
    public enum Sky {
        Sun(1), Earth(2), Moon("moon");

        Sky(String moon) {
        }

        Sky(int i) {
        }
    }

    public static void main(String[] args) {
        var x = Sky.Sun;
        System.out.println(x == Sky.Moon);//false
        System.out.println(x == Sky.Sun);//true
        System.out.println(x);//Sun
    }
}

枚举的实现

枚举其实就相当于一个类拥有一些静态实例。以下代码,先改一下Sky.Sun的value,然后重新获取一个Sky.Sun,会发现它的值已经被修改了,这说明Sky.Sun是一个全局的单例。

public class UseEnum {
    public enum Sky {
        Sun(1), Earth(2), Moon(3);
        int value;

        Sky(int i) {
            this.value = i;
        }

    }

    public static void main(String[] args) {
        var x = Sky.Sun;
        x.value = 100;
        var y = Sky.Sun;
        System.out.println(y.value);//输出100
    }
}

以上代码等价于实现一个静态类,然后为它实现一些单例。

public class UseEnum {
    static class SkyClass {
        public final static SkyClass Sun = new SkyClass(1);
        public final static SkyClass Earth = new SkyClass(2);
        public final static SkyClass Moon = new SkyClass(3);
        int value;

        SkyClass(int x) {
            this.value = value;
        }
    }

    public static void main(String[] args) {
        var x = SkyClass.Sun;
        x.value = 100;
        var y = SkyClass.Sun;
        System.out.println(y.value);
    }
}

枚举最佳实践

如果涉及到序列化反序列化,最好不要使用枚举。因为枚举的valueOf()必须传入一个明确的枚举值,否则抛出异常。例如有两个服务A和B,它们之间通信的时候B增加了一个枚举值而A没有增加枚举值,这就导致A执行反序列化的时候抛出异常。

对于像错误码这种数据,不要使用枚举,因为 错误码是不断添多的,Java的枚举扩展性较差。

Java中枚举的最佳实践可能还是使用静态成员变量+int值的形式。

public class Gender {
    public final static int Unknown = 0;
    public final static int Male = 1;
    public final static int Female = 2;
}