java的枚举定义以及使用方法介绍



原始的接口定义常量——一般定义常量的方法

public interface IConstants {
    String MON = "Mon";
    String TUE = "Tue";
    String WED = "Wed";
    String THU = "Thu";
    String FRI = "Fri";
    String SAT = "Sat";
    String SUN = "Sun";
}

枚举语法(定义)

    1、创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.lang.Enum 类的子类(java.lang.Enum 是一个抽象类)。
    2、枚举类型符合通用模式 Class Enum<E extends Enum<E>>,而 E 表示枚举类型的名称。
    3、枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal) 构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。
package com.hmw.test;
/**
 * 枚举测试类
 * @author <a href="mailto:[email protected]">何明旺</a>
 */
public enum EnumTest {
    MON, TUE, WED, THU, FRI, SAT, SUN;
}
这段代码实际上调用了7次 Enum(String name, int ordinal):
new Enum<EnumTest>("MON",0);
new Enum<EnumTest>("TUE",1);
new Enum<EnumTest>("WED",2);
..............
遍历、switch 等常用操作
对enum进行遍历和switch的操作示例代码:
public class Test {
    public static void main(String[] args) {
        for (EnumTest e : EnumTest.values()) {
            System.out.println(e.toString());
        }
         
        System.out.println("----------------我是分隔线------------------");
         
        EnumTest test = EnumTest.TUE;
        switch (test) {
        case MON:
            System.out.println("今天是星期一");
            break;
        case TUE:
            System.out.println("今天是星期二");
            break;
        // ... ...
        default:
            System.out.println(test);
            break;
        }
    }
}
输出结果为:
MON
TUE
WED
THU
FRI
SAT
SUN
----------------我是分隔线------------------
今天是星期二

enum 对象的常用方法介绍

1、比较此枚举与指定对象的顺序。
int compareTo(E o) 
2、返回与此枚举常量的枚举类型相对应的 Class 对象。
Class<E> getDeclaringClass() 
3、 返回此枚举常量的名称,在其枚举声明中对其进行声明。
String name() 
4、返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
int ordinal() 
5、 返回枚举常量的名称,它包含在声明中。
String toString()
6、返回带指定名称的指定枚举类型的枚举常量。
static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) 
public class Test {
    public static void main(String[] args) {
        EnumTest test = EnumTest.TUE;
         
        //compareTo(E o)
        switch (test.compareTo(EnumTest.MON)) {
        case -1:
            System.out.println("TUE 在 MON 之前");
            break;
        case 1:
            System.out.println("TUE 在 MON 之后");
            break;
        default:
            System.out.println("TUE 与 MON 在同一位置");
            break;
        }
         
        //getDeclaringClass()
        System.out.println("getDeclaringClass(): " + test.getDeclaringClass().getName());
         
        //name() 和  toString()
        System.out.println("name(): " + test.name());
        System.out.println("toString(): " + test.toString());
         
        //ordinal(), 返回值是从 0 开始
        System.out.println("ordinal(): " + test.ordinal());
    }
}
输出结果:
TUE 在 MON 之后
getDeclaringClass(): com.hmw.test.EnumTest
name(): TUE
toString(): TUE
ordinal(): 1

给 enum 自定义属性和方法
给 enum 对象加一下 value 的属性和 getValue() 的方法:

package com.hmw.test;
 
/**
 * 枚举测试类
 * 
 * @author <a href="mailto:[email protected]">何明旺</a>
 */
public enum EnumTest {
    MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6) {
        @Override
        public boolean isRest() {
            return true;
        }
    },
    SUN(0) {
        @Override
        public boolean isRest() {
            return true;
        }
    };
 
    private int value;
 
    private EnumTest(int value) {
        this.value = value;
    }
 
    public int getValue() {
        return value;
    }
 
    public boolean isRest() {
        return false;
    }
}
public class Test {
    public static void main(String[] args) {
        System.out.println("EnumTest.FRI 的 value = " + EnumTest.FRI.getValue());
    }
}
输出结果为:
EnumTest.FRI 的 value = 5

EnumSet,EnumMap 的应用

public class Test {
    public static void main(String[] args) {
        // EnumSet的使用
        EnumSet<EnumTest> weekSet = EnumSet.allOf(EnumTest.class);
        for (EnumTest day : weekSet) {
            System.out.println(day);
        }
 
        // EnumMap的使用
        EnumMap<EnumTest, String> weekMap = new EnumMap(EnumTest.class);
        weekMap.put(EnumTest.MON, "星期一");
        weekMap.put(EnumTest.TUE, "星期二");
        // ... ...
        for (Iterator<Entry<EnumTest, String>> iter = weekMap.entrySet().iterator(); iter.hasNext();) {
            Entry<EnumTest, String> entry = iter.next();
            System.out.println(entry.getKey().name() + ":" + entry.getValue());
        }
    }
}

原理分析

        enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个class文件。
        该class文件经过反编译可以看到实际上是生成了一个类,该类继承了java.lang.Enum<E>。
        EnumTest 经过反编译(javap com.hmw.test.EnumTest 命令)之后得到的内容如下:
public class com.hmw.test.EnumTest extends java.lang.Enum{
    public static final com.hmw.test.EnumTest MON;
    public static final com.hmw.test.EnumTest TUE;
    public static final com.hmw.test.EnumTest WED;
    public static final com.hmw.test.EnumTest THU;
    public static final com.hmw.test.EnumTest FRI;
    public static final com.hmw.test.EnumTest SAT;
    public static final com.hmw.test.EnumTest SUN;
    static {};
    public int getValue();
    public boolean isRest();
    public static com.hmw.test.EnumTest[] values();
    public static com.hmw.test.EnumTest valueOf(java.lang.String);
    com.hmw.test.EnumTest(java.lang.String, int, int, com.hmw.test.EnumTest);
}
所以,实际上 enum 就是一个 class,只不过 java 编译器帮我们做了语法的解析和编译而已。
总结
    可以把 enum 看成是一个普通的 class,它们都可以定义一些属性和方法,


    不同之处是:enum 不能使用 extends 关键字继承其他类,因为 enum 已经继承了 java.lang.Enum(java是单一继承)。


Java 枚举7常见种用法

用法一:常量

package javaEnum;
/**
 * Created by cyg521 on 2018/1/17.
 */
//constant  常量
public class TestEnumByConstant {
    //创建枚举类-----用法一常量
    enum Color {
        red , bule , white ,  black
    }
    public static void main(String[] args){
        //测试枚举类-----用法一常量
        System.out.println(Color.black);
        System.out.println(Color.red);
        System.out.println(Color.bule);
        System.out.println(Color.white);
    }
}

用法二:switch

package javaEnum;
/**
 * Created by cyg521 on 2018/1/17.
 */
public class TestEnumBySwitch {
    //创建枚举类-----用法二使用switch
    enum Color2{
        red , yeellow , green
    }
    Color2 c = Color2.green;
    public void change(){
        switch (c){
            case red:
                c = Color2.red;
                System.out.println(c);
                break;
            case green:
                c = Color2.green;
                System.out.println(c);
                break;
            case yeellow:
                c = Color2.yeellow;
                System.out.println(c);
                break;
        }
    }
    public static void main(String[] args){
        Color2[] d = Color2.values();
        TestEnumBySwitch a = new TestEnumBySwitch();
        a.change();
        for (int i=0 ;i<d.length ; i++){
            Color2 c = d[i];
            System.out.println(d[i]);
            switch (c){
                case red:
                    c = Color2.red;
                    System.out.println(c);
                    break;
                case green:
                    c = Color2.green;
                    System.out.println(c);
                    break;
                case yeellow:
                    c = Color2.yeellow;
                    System.out.println(c);
                    break;
            }
        }
    }
}

用法三:向枚举中添加新方法

package javaEnum;
import java.util.Scanner;
/**
 * Created by cyg521 on 2018/1/17.
 */
//向枚举中添加新方法
public class TestEnumByAddNewMethod {
    /**
     * 如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。
     * 可以理解为创建枚举的自定义方法编写
     */
    enum Color{
        RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
        //成员变量
        private String name ;
        private int index;
        //构造方法
        private Color(String name, int index) {
            this.name = name;
            this.index = index;
        }
        //普通方法
        public static String getName(int index){
            for (Color c: Color.values()) {
                if (c.getIndex() == index){
                    return c.name;
                }
            }
            return null ;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getIndex() {
            return index;
        }
        public void setIndex(int index) {
            this.index = index;
        }
    }
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入代表颜色的下标1~4");
        int i = sc.nextInt();
        if( 0<=i&& i<=4){
            System.out.println("你输入的颜色下标代表的颜色为:  "+Color.getName(i));
        }else {
            System.out.println("你输入的颜色下标不存在对应的颜色;");
        }
    }
}

用法四:覆盖枚举的方法

package javaEnum;
/**
 * Created by cyg521 on 2018/1/17.
 */
//覆盖枚举的方法
public class TestEnumByOverride {
    public enum Color {
        RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
        // 成员变量
        private String name;
        private int index;
        // 构造方法
        private Color(String name, int index) {
            this.name = name;
            this.index = index;
        }
        //覆盖方法
        @Override
        public String toString() {
            return this.index+"_"+this.name;
        }
    }
    public static void main(String[] args){
        Color[] c =  Color.values();
        for (Color color:c) {
            System.out.println(color.toString());
        }
    }
}  

用法五:实现接口

package javaEnum;
/**
 * Created by cyg521 on 2018/1/17.
 */
public class TestEnumByInterFace {
    public enum Color implements Behaviour{
        RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
        // 成员变量
        private String name;
        private int index;
        // 构造方法
        private Color(String name, int index) {
            this.name = name;
            this.index = index;
        }
        //接口方法
        @Override
        public String getInfo() {
            return this.name;
        }
        //接口方法
        @Override
        public void print() {
            System.out.println(this.index+":"+this.name);
        }
    }
    public static void main(String[] args){
        Color[] colors = Color.values();
        for (Color color:colors) {
            System.out.println(color.getInfo());
            color.print();
        }
    }
}
interface Behaviour {
    void print();
    String getInfo();
}

用法六:使用接口组织枚举

package javaEnum;
import com.sun.deploy.util.ArrayUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * Created by cyg521 on 2018/1/17.
 */
public class TestEnumByInterfaces {
    public interface Food {
        enum Coffee implements Food{
            BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
        }
        enum Dessert implements Food{
            FRUIT, CAKE, GELATO
        }
    }
    //数组合并方法
    public static void main(String[] args){
        Food[] foods1 = Food.Coffee.values();
        Food[] foods2 = Food.Dessert.values();
        List list = new ArrayList(Arrays.asList(foods1));
        list.addAll(Arrays.asList(foods2));
        Object[] foods =   list.toArray();
        for (Object food:foods) {
            System.out.println(food);
        }
        System.out.println(Arrays.toString(foods));
    }
}


用法七:关于枚举集合的使用

java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型。关于这个两个集合的使用就不在这里赘述,可以参考JDK文档。
关于枚举的实现细节和原理请参考:
参考资料:《ThinkingInJava》第四版











猜你喜欢

转载自blog.csdn.net/cyg521/article/details/79092341
今日推荐