Java枚举类使⽤场景及实例解析
为什么要⽤枚举类
什么场景会⽤到枚举,⽐如在表⽰⼀周的某⼀天,⼀年中的四季,这样⼀组常量的时候我们会⽤到枚举。在Java引⼊枚举类之前常⽤⼀组int常量来表⽰枚举,这种⽅式称为int枚举模式(int enum pattern)。
private static final int MONDAY = 1;
private static final int TUESDAY = 2;
private static final int WEDNESDAY = 3;
private static final int THURSDAY = 4;
private static final int CODE_START = 1;
private static final int CODE_STATUS = 2;
private static final int CODE_STOP = 3;
enum类型如何使用这种我们⾮常习惯的模式其实存在着很多不⾜和问题,
int枚举组不具备命名空间的能⼒,当表⽰具有相同命名常量时,需要添加前缀避免冲突
int表⽰的枚举值不具有描述性,需要遍历判断具体的值并添加描述
int枚举模式不具有安全性,此外int类型是编译时常量,如果与int枚举常量关联的值发⽣变化,必须重新编译,不重新编译虽然不影响运⾏,但是准确性已经不能保证
即便是升级为⽤String来表⽰枚举值,String枚举模式(String enum pattern),但这样同样存在其他问题,
初学者容易直接把字符串常量硬编码到代码中,不使⽤对应的常量字段(filed)名,⼀旦书写错误,编译器⽆法检查,但在运⾏时会报出异常
String枚举模式会存在⼀定的性能问题,涉及到字符串的⽐较操作
因此Java引⼊了枚举类型解决int和String枚举模式带来的诸多不⾜,枚举类型保证了编译时的类型安全,枚举类型有⾃⼰独⽴的命名空间,枚举类型便于扩展,可以添加⽅法和域实现其他的外部接⼝。
如何使⽤枚举类
创建枚举类
Java中枚举是⼀种特殊的引⽤类型,是类(Class)的⼀种,JDK1.5中开始引⼊枚举类型,在Java中使⽤enum关键字来声明枚举类,枚举类编译后默认继承了java.lang.Enum,因此枚举类不能在继承其他类,枚举⼀般⽤来声明某⼀特定类型的有穷集合,如⽤枚举表⽰四季
public enum Season {
SPRING,SUMMER,FALL,WINTER
}
枚举类API
参考JDK api 1.8.CHM,可以看到枚举类的常⽤api如下:
name public final String name()
返回此枚举常量的名称,与其枚举声明中声明的完全相同。⼤多数程序员应该使⽤toString()⽅法,因为toString⽅法可能会返回⼀个更加⽤户友好的名称。该⽅法主要⽤于专门的情况,其中正确性取决于获得确切的名称,这从发布到发布不会有所不同。
ordinal public final int ordinal()
返回此枚举常数的序数(其枚举声明中的位置,其中初始常数的序数为零)。⼤多数程序员将不会使⽤这种⽅法。它被设计为使⽤复杂的基于枚举的数据结构,如EnumSet和EnumMap 。
toString public String toString()
返回声明中包含的此枚举常量的名称。该⽅法可以被覆盖,尽管它通常不是必需或不可取的。当⼀个更“程序员友好”的字符串形式存在时,枚举类型应该覆盖此⽅法。
重写: toString 在 Object
compareTo public final int compareTo(E o)
将此枚举与指定的对象进⾏⽐较以进⾏订购。返回⼀个负整数,零或正整数,因为该对象⼩于,等于或⼤于指定对象。枚举常数仅与相同枚举类型的其他枚举常量相当。该⽅法实现的⾃然顺序是声明常量的顺序。
Specified by: compareTo 在界⾯Comparable<E extends Enum<E>
参数:o - 要⽐较的对象。
结果:负整数,零或正整数,因为该对象⼩于,等于或⼤于指定对象。
getDeclaringClass public final Class<E> getDeclaringClass()
返回与此枚举常量的枚举类型相对应的Class对象。当且仅当e1.getDeclaringClass()== e2.getDeclaringClass())时,两个枚举常量e1和e2具有相同的枚举类型。(此⽅法返回的值可能与使⽤常量特定类体的枚举常数Class()⽅法返回的值不同)
结果:该类对象对应于此枚举常量的枚举类型
valueOf public static <T extends Enum<T>> T valueOf(Class <T> enumType,String name)
返回具有指定名称的指定枚举类型的枚举常量。该名称必须与⽤于声明此类型的枚举常量的标识符完全⼀致。(不允许使⽤外来空⽩字符。)
请注意,对于特定枚举类型T ,可以使⽤该枚举上隐式声明的public static T valueOf(String)⽅法,⽽不是使⽤此⽅法将名称映射到
相应的枚举常量。枚举类型的所有常量可以通过调⽤该类型的隐式public static T[] values()⽅法来获得。
values
此⽅法并未在API中提供,返回枚举类型所有对象实例,返回值枚举类型的数组。
枚举应⽤案例
上⾯简单描述了如何声明⼀个枚举类,这⾥结合实际应⽤场景描述枚举的其他⽤法
单例设计模式
说到单例模式很多⼈会⽐较熟悉懒汉、饿汉等常见的单例书写模式,⽤枚举表⽰枚举还是⽐较少见的,对于单例设计模式的多种写法,单元素的枚举类型已经成为实现Singleton的最佳⽅法。⾸先回顾下单例设计模式要求满⾜的特点:
构造⽅法私有化;
实例化的变量引⽤私有化;
获取实例的⽅法共有。
public enum Singleton {
INSTANCE;
public Singleton getInstance(){
return INSTANCE;
}
}
使⽤枚举⽅式创建单例的好处:
避免反射攻击
避免序列化问题
有穷对象集合
枚举类型中的构造器默认私有化,只能添加private修饰或者不添加
枚举类型中定义的抽象⽅法必须被所有常量中的具体⽅法所覆盖,特定于常量的⽅法实现可以结合特定于常量的数据结合起来
⽤枚举表⽰加减乘除的操作
public enum Operation {
PLUS("+","加法"){
public double apply(double x,double y){
return x + y;
}
},
MINUS("-","减法"){
public double apply(double x,double y){
return x - y;
}
},
TIMES("*","乘法"){
public double apply(double x,double y){
return x * y;
}
},
DIVIDE("/","除法"){
public double apply(double x,double y){
return x / y;
}
};
private final String symbol;
private final String operName;
public String getSymbol() {
return symbol;
}
public String getOperName() {
return operName;
}
Operation(String symbol, String operName){
this.symbol = symbol;
this.operName = operName;
}
public abstract double apply(double x,double y);
}
调⽤枚举中的⽅法
public class TestOpera {
public static void main(String[] args) {
double x = 1;
double y = 1;
for(Operation operate : Operation.values()){
System.out.println(
);
}
}
}
输出结果
加法:1.0 + 1.0 = 2.0
减法:1.0 - 1.0 = 0.0
乘法:1.0 * 1.0 = 1.0
除法:1.0 / 1.0 = 1.0
引⼊枚举类型,不仅可以描述枚举本⾝,还可以添加描述性字符串,甚⾄给每个对象添加结合特有常量的⾏为,也不⽤考虑其他安全性为题。
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。