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;
}