java枚舉詳解



       enum實現:



               jdk5中增加了一種新類型[也可以說是一種語法糖]---枚舉,

       


下面介紹一些常用的用法:


    第一:常量


public enum Season{
	SPRING,
	SUMMER,
	AUTUMN,
	WINTER
}


查看一下枚舉的字節碼:

Compiled from "Season.java"
public final class Season extends java.lang.Enum
  Signature: length = 0x2
   00 23 
  SourceFile: "Season.java"
  minor version: 0
  major version: 51
  Constant pool:
const #1 = Field	#4.#38;	//  Season.$VALUES:[LSeason;
const #2 = Method	#39.#40;	//  "[LSeason;".clone:()Ljava/lang/Object;
const #3 = class	#23;	//  "[LSeason;"
const #4 = class	#41;	//  Season
const #5 = Method	#16.#42;	//  java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
const #6 = Method	#16.#43;	//  java/lang/Enum."<init>":(Ljava/lang/String;I)V
const #7 = String	#17;	//  SPRING
const #8 = Method	#4.#44;	//  Season."<init>":(Ljava/lang/String;I)V
const #9 = Field	#4.#45;	//  Season.SPRING:LSeason;
const #10 = String	#19;	//  SUMMER
const #11 = Field	#4.#46;	//  Season.SUMMER:LSeason;
const #12 = String	#20;	//  AUTUMN
const #13 = Field	#4.#47;	//  Season.AUTUMN:LSeason;
const #14 = String	#21;	//  WINTER
const #15 = Field	#4.#48;	//  Season.WINTER:LSeason;
const #16 = class	#49;	//  java/lang/Enum
const #17 = Asciz	SPRING;
const #18 = Asciz	LSeason;;
const #19 = Asciz	SUMMER;
const #20 = Asciz	AUTUMN;
const #21 = Asciz	WINTER;
const #22 = Asciz	$VALUES;
const #23 = Asciz	[LSeason;;
const #24 = Asciz	values;
const #25 = Asciz	()[LSeason;;
const #26 = Asciz	Code;
const #27 = Asciz	LineNumberTable;
const #28 = Asciz	valueOf;
const #29 = Asciz	(Ljava/lang/String;)LSeason;;
const #30 = Asciz	<init>;
const #31 = Asciz	(Ljava/lang/String;I)V;
const #32 = Asciz	Signature;
const #33 = Asciz	()V;
const #34 = Asciz	<clinit>;
const #35 = Asciz	Ljava/lang/Enum<LSeason;>;;
const #36 = Asciz	SourceFile;
const #37 = Asciz	Season.java;
const #38 = NameAndType	#22:#23;//  $VALUES:[LSeason;
const #39 = class	#23;	//  "[LSeason;"
const #40 = NameAndType	#50:#51;//  clone:()Ljava/lang/Object;
const #41 = Asciz	Season;
const #42 = NameAndType	#28:#52;//  valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
const #43 = NameAndType	#30:#31;//  "<init>":(Ljava/lang/String;I)V
const #44 = NameAndType	#30:#31;//  "<init>":(Ljava/lang/String;I)V
const #45 = NameAndType	#17:#18;//  SPRING:LSeason;
const #46 = NameAndType	#19:#18;//  SUMMER:LSeason;
const #47 = NameAndType	#20:#18;//  AUTUMN:LSeason;
const #48 = NameAndType	#21:#18;//  WINTER:LSeason;
const #49 = Asciz	java/lang/Enum;
const #50 = Asciz	clone;
const #51 = Asciz	()Ljava/lang/Object;;
const #52 = Asciz	(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;;

{
public static final Season SPRING;

public static final Season SUMMER;

public static final Season AUTUMN;

public static final Season WINTER;

public static Season[] values();
  Code:
   Stack=1, Locals=0, Args_size=0
   0:	getstatic	#1; //Field $VALUES:[LSeason;
   3:	invokevirtual	#2; //Method "[LSeason;".clone:()Ljava/lang/Object;
   6:	checkcast	#3; //class "[LSeason;"
   9:	areturn
  LineNumberTable: 
   line 1: 0


public static Season valueOf(java.lang.String);
  Code:
   Stack=2, Locals=1, Args_size=1
   0:	ldc_w	#4; //class Season
   3:	aload_0
   4:	invokestatic	#5; //Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
   7:	checkcast	#4; //class Season
   10:	areturn
  LineNumberTable: 
   line 1: 0


static {};
  Code:
   Stack=4, Locals=0, Args_size=0
   0:	new	#4; //class Season
   3:	dup
   4:	ldc	#7; //String SPRING
   6:	iconst_0
   7:	invokespecial	#8; //Method "<init>":(Ljava/lang/String;I)V
   10:	putstatic	#9; //Field SPRING:LSeason;
   13:	new	#4; //class Season
   16:	dup
   17:	ldc	#10; //String SUMMER
   19:	iconst_1
   20:	invokespecial	#8; //Method "<init>":(Ljava/lang/String;I)V
   23:	putstatic	#11; //Field SUMMER:LSeason;
   26:	new	#4; //class Season
   29:	dup
   30:	ldc	#12; //String AUTUMN
   32:	iconst_2
   33:	invokespecial	#8; //Method "<init>":(Ljava/lang/String;I)V
   36:	putstatic	#13; //Field AUTUMN:LSeason;
   39:	new	#4; //class Season
   42:	dup
   43:	ldc	#14; //String WINTER
   45:	iconst_3
   46:	invokespecial	#8; //Method "<init>":(Ljava/lang/String;I)V
   49:	putstatic	#15; //Field WINTER:LSeason;
   52:	iconst_4
   53:	anewarray	#4; //class Season
   56:	dup
   57:	iconst_0
   58:	getstatic	#9; //Field SPRING:LSeason;
   61:	aastore
   62:	dup
   63:	iconst_1
   64:	getstatic	#11; //Field SUMMER:LSeason;
   67:	aastore
   68:	dup
   69:	iconst_2
   70:	getstatic	#13; //Field AUTUMN:LSeason;
   73:	aastore
   74:	dup
   75:	iconst_3
   76:	getstatic	#15; //Field WINTER:LSeason;
   79:	aastore
   80:	putstatic	#1; //Field $VALUES:[LSeason;
   83:	return
  LineNumberTable: 
   line 2: 0
   line 3: 13
   line 4: 26
   line 5: 39
   line 1: 52


}




上面介紹定義了四個常量:春夏秋冬,


從字節碼可以看出,Season繼承了 java.lang.Enum,四個枚舉常量就是類中放入常量。具體的Enum源碼 解析查看我的另一篇文章~


第二:增加switch用法

JDK1.6之前的switch語句只支持int,char,enum類型,使用枚舉,能讓我們的代碼可讀性更強。

enum Signal{
	GREEN,
	YELLOW,
	RED
}

public class TrafficLight{
	Signal color=Signal.RED;
	public void change(){
		switch(color){
			case RED:
				color=Signal.GREEN;
				break;
			case YELLOW:
				color=Signal.RED;
				break;
			case GREEN:
				color=Signal.YELLOW;
				break;
		}
	}
}

用法三:向枚舉中增加新的方法:

如果打算自定義自己的方法,那麼必須在enum實例序列的最後添加一個分號。而且 Java 要求必須先定義 enum 實例。


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;  
    }  
    // 普通方法  
    public static String getName(int index) {  
        for (Color c : Color.values()) {  
            if (c.getIndex() == index) {  
                return c.name;  
            }  
        }  
        return null;  
    }  
    // get set 方法  
    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;  
    }  
}  

用法四:實現接口


所有的枚舉都繼承自java.lang.Enum類。由於Java 不支持多繼承,所以枚舉對象不能再繼承其他類,但是可以實現接口

package com.panther.dong.enumtest;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by panther on 16-9-30.
 */
public enum EnumTest implements Operation {
    PLUS("+") {
        @Override
        public int operate(int arg1, int arg2) {
            return arg1 + arg2;
        }
    },
    SUB("-") {
        @Override
        public int operate(int arg1, int arg2) {
            return arg1 - arg2;
        }
    };


    final String operation;

    EnumTest(String operation) {
        this.operation = operation;
    }

    public static void main(String[] args) {
        Map<String, EnumTest> enumTestMap = new HashMap<String, EnumTest>();
        enumTestMap.put("+", EnumTest.PLUS);
        enumTestMap.put("-", EnumTest.SUB);
        Operation operation = enumTestMap.get("-");
        System.out.println(operation.operate(1, 2));
    }

}

interface Operation {
    int operate(int arg1, int arg2);
}


用法五:使用接口組織枚舉

public interface Food {  
    enum Coffee implements Food{  
        BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO  
    }  
    enum Dessert implements Food{  
        FRUIT, CAKE, GELATO  
    }  
}  

用法六:關於枚舉集合的使用


java.util.EnumSetjava.util.EnumMap是兩個枚舉集合。EnumSet保證集合中的元素不重複;EnumMap中的key是enum類型,而value則可以是任意類型

  



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章