java:枚举类
1 介绍
使用枚举类型可以取代以往定义常量的方式,同时枚举类型还赋予程序在编译时进行检查的功能。当需要定义一组常量时,强烈建议使用枚举类。
枚举类的实现:JDK1.5之前需要自定义枚举类,JDK1.5新增的enum关键字用于定义枚举类。若枚举类只有一个对象,则可以作为一种单例模式的实现方式。枚举类的属性:枚举类对象的属性不应允许被改动,所以应该是使用private final修饰,枚举类使用private final修饰的属性应该在构造器中为其赋值,若枚举类显式的定义了带参数的构造器,则在列出枚举值时也必须对应的传入参数。
以往设置常量,通常将常量放置在接口中。该常量的修饰符为static和final。(接口中的属性默认是static和final的)
interface Constants{
public static final int Constants_A=1;
public static final int Constants_B=2;
}
枚举类型定义如下:
enum Constant{
Constants_A,
Constants_B,
Constants_C
}
2 初识枚举
在run方法中,任意传递参数会报错,因为该方法只接受枚举类型的常量作为其参数,具有参数类型检测的优势。
另外,可以将枚举类型看作是一个类,它继承于java.lang.Enum类,
public class Enu {
public static void main(String[] args) {
System.out.println(Constant.Constants_A);
System.out.println(Constant.Constants_C);
run(Constant.Constants_C);
run(Constant.Constants_B);
}
public static void run(Constant c){
switch(c){
case Constants_A:
System.out.println("我是A");
break;
case Constants_B:
System.out.println("我是B");
break;
}
}
}
interface Constants{
public static final int Constants_A=1;
public static final int Constants_B=2;
}
enum Constant{
Constants_A(2,"大A"),
Constants_B(4,"中B"),
Constants_C(3,"小C");
private int code;
private String description;
private Constant(int code,String description){
this.code=code;
this.description=description;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
public void setCode(int code) {
this.code = code;
}
public void setDescription(String description) {
this.description = description;
}
}
Constants_A
Constants_C
我是B
System.out.println(Constant.class.getSuperclass());
//class java.lang.Enum
另外的写法:
package com.base;
public class Enum2 {
public static void main(String[] args) {
System.out.println(Aer.U1.getCode());;
}
}
enum Aer{
//枚举类的实例对象(也就是每个枚举值对象),必须写在前面(在类成员变量、构造方法、实例方法等前面)
U1("100","你好"),
U2("200","我好");
//java中,类成员变量,如果是final,那么必须赋值,如果不赋值,就可以在构造方法中加入改参数
private final String code;
private final String desc;
//枚举类默认构造方法是private的,可以不写
Aer(String code, String desc){
this.code=code;
this.desc=desc;
}
public String getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
100
3 Enum类的主要方法
可以将枚举类型看作是一个类。每一个枚举类型成员可以看作是枚举类型的一个实例,这些枚举类型成员都默认被final、public、static修饰,所以当使用枚举类型成员时直接使用枚举类型名称调用枚举类型成员即可。
常用方法,values\valueOf:类方法,compareTo\ordinal\name:实例方法。
方法名:详细描述
3.1 valueOf:传递枚举类型的Class对象和枚举常量名称给静态方法valueOf,会得到与参数匹配的枚举常量。
public static void main(String[] args) {
System.out.println(Constant.valueOf("Constants_A"));
System.out.println(Constant.valueOf("Constants_D"));
}
3.2 toString:得到当前枚举常量的名称,可以通过重写该方法使得到的结果更易读。
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public class Enu {
public static void main(String[] args) {
System.out.println(Constant.valueOf("Constants_A"));
System.out.println(Constant.Constants_A);
System.out.println(Constant.valueOf("Constants_C"));
}
}
enum Constant{
Constants_A(2,"大A"),
Constants_B(4,"中B"),
Constants_C(3,"小C");
private int code;
private String description;
private Constant(int code,String description){
this.code=code;
this.description=description;
}
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
public void setCode(int code) {
this.code = code;
}
public void setDescription(String description) {
this.description = description;
}
}
//结果如下:
Constant[code=2,description=大A,name=Constants_A,ordinal=0]
Constant[code=2,description=大A,name=Constants_A,ordinal=0]
Constant[code=3,description=小C,name=Constants_C,ordinal=2]
3.3 values:返回枚举类型的对象数组。该方法可以很方便的遍历所有的枚举值。
public static void main(String[] args) {
Constant[] a=Constant.values();
List<Constant> l= Arrays.asList(Constant.values());
System.out.println(Arrays.asList(a));
Consumer<Constant> c= System.out::println;
l.forEach(c);
}
[Constant[code=2,description=大A,name=Constants_A,ordinal=0], Constant[code=4,description=中B,name=Constants_B,ordinal=1], Constant[code=3,description=小C,name=Constants_C,ordinal=2]]
Constant[code=2,description=大A,name=Constants_A,ordinal=0]
Constant[code=4,description=中B,name=Constants_B,ordinal=1]
Constant[code=3,description=小C,name=Constants_C,ordinal=2]
3.4 equals:在枚举类型中可以直接使用" == "来比较两个枚举常量是否相等。Enum提供的equals(),也是直接使用 '=='实现的。它的存在是为了在Set、List和Map中使用。注意,equals()是不可变的。
3.5 hashCode:Enum实现了hashCode()来和equals()保持一致。它也是不可变的。
3.6 getDeclaringClass:得到枚举常量所属枚举类型的Class对象。可以用它来判断两个枚举常量是否属于同一个枚举类型。
3.7 name:得到当前枚举常量的名称。建议优先使用toString()。
name()和ordinal()、compareTo()等类似,是实例方法,由枚举类型成员调用。
import static java.lang.System.out;
public static void main(String[] args) {
Constant[] c=Constant.values();
for (Constant constant : c) {
out.println(constant.name());
}
}
Constants_A
Constants_B
Constants_C
3.8 ordinal:得到当前枚举常量的次序。
public static void main(String[] args) {
Constant[] c=Constant.values();
for (Constant constant : c) {
out.println(constant+"顺序如下:"+constant.ordinal());
}
}
Constants_A顺序如下:0
Constants_B顺序如下:1
Constants_C顺序如下:2
ordinal:按照枚举类型成员定义顺序,从0开始。
3.9 compareTo:枚举类型实现了Comparable接口,这样可以比较两个枚举常量的大小(按照声明的顺序排列,即枚举对象定义时的顺序)。
import static java.lang.System.out;
public class Enu {
public static void main(String[] args) {
Constant[] c=Constant.values();
for (Constant constant : c) {
out.println(Constant.Constants_B+"与"+constant+"比较结果:"
+Constant.Constants_B.compareTo(constant));
}
}
}
enum Constant{
Constants_A(2,"大A"),
Constants_B(4,"中B"),
Constants_C(3,"小C");
private int code;
private String description;
private Constant(int code,String description){
this.code=code;
this.description=description;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
public void setCode(int code) {
this.code = code;
}
public void setDescription(String description) {
this.description = description;
}
}
Constants_B与Constants_A比较结果:1
Constants_B与Constants_B比较结果:0
Constants_B与Constants_C比较结果:-1
compareTo返回的结果:正值代表方法中参数在调用该方法的枚举对象位置之前;0代表两个互相比较的枚举成员的位置相同;负值代表方法中参数在调用该方法的枚举对象位置之后。
3.10 clone:枚举类型不能被clone。为了防止子类实现克隆方法,Enum实现了一个仅抛出CloneNotSupportedException异常的不变clone()。
4 enum枚举类实现接口
4.1 继承接口并重写方法
import static java.lang.System.out;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public class Enu {
public static void main(String[] args) {
Constant[] c=Constant.values();
for (Constant constant : c) {
constant.show();
}
}
}
interface Extra{
void show();
}
enum Constant implements Extra{
Constants_A(2,"大A"),
Constants_B(4,"中B"),
Constants_C(3,"小C"),
Constants_D();
private int code;
private String description;
private Constant(){
}
private Constant(int code,String description){
this.code=code;
this.description=description;
}
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
public void setCode(int code) {
this.code = code;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public void show() {
out.println("我是重写的方法");
}
}
我是重写的方法
我是重写的方法
我是重写的方法
我是重写的方法
4.2 针对不同的枚举类型成员,实现不同的接口的方法
tips:idea快速为重写方法加上重写的注解:直接输入接口中重写的方法名,enter即可。
import static java.lang.System.out;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public class Enu {
public static void main(String[] args) {
Constant[] c=Constant.values();
for (Constant constant : c) {
constant.show();
}
}
}
interface Extra{
void show();
}
enum Constant implements Extra{
Constants_A(2,"大A"){
@Override
public void show() {
out.println("我是大的A");
}
},
Constants_B(4,"中B"){
@Override
public void show() {
out.println("我是中的B");
}
},
Constants_C(3,"小C"){
@Override
public void show() {
out.println("我是小的C");
}
},
Constants_D(){
@Override
public void show() {
out.println("我是无参的D");
}
};
private int code;
private String description;
private Constant(){
}
private Constant(int code,String description){
this.code=code;
this.description=description;
}
@Override
public String toString(){
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
public void setCode(int code) {
this.code = code;
}
public void setDescription(String description) {
this.description = description;
}
}
我是大的A
我是中的B
我是小的C
我是无参的D
5 总结
枚举类型提供了一种用户友好的变量定义方法。特点如下:
类型安全;
紧凑有效的数据定义;
可以和程序其他部分完美交互;
运行效率高。