enum一個最不像class的class
java枚舉類型是jdk5出現的.它的出現主要爲了解決一些有特殊意義,已經肯定的,長度不會改變的集合.java
//月份描述 public class Month { //月份名稱 private final String name; //月份天數 private final int days; //構造子,給出一個月份名稱,默認天數31天 private Month(String name) { this(name, 31); } //構造子,給出月份名稱,月份天數 private Month(String name, int days) { this.name = name; this.days = days; } /* * 建立12個月份 * */ public static final Month JAN = new Month("January"); public static final Month FEB = new Month("February", 28); public static final Month MAR = new Month("March"); public static final Month APR = new Month("April", 30); public static final Month MAY = new Month("May"); public static final Month JUN = new Month("June", 30); public static final Month JUL = new Month("July"); public static final Month AUG = new Month("August"); public static final Month SEP = new Month("September", 30); public static final Month OCT = new Month("October"); public static final Month NOV = new Month("November", 30); public static final Month DEC = new Month("December"); //獲取月份名稱 public String getName() { return name; } //獲取月份值 public int getDays() { return days; } }
public class Main { public static void main(String[] args) { System.out.println(Month.JAN);//demo7.Month@1b6d3586 System.out.println(Month.JAN.getName());//January System.out.println(Month.JAN.getDays());//31 } }
以上代碼是建立了一個不可改變的月份表.內部實現就是一個在一個類中建立了12個實例對象.在客戶端無需建立,直接獲取沒有月份的相關屬性.以上寫法在沒有enum類型出現前,是最實用的寫法.咱們也能夠看出函數
在enum類中,只提供查詢方法,不提供修改方法.this
在jdk1.5之後,建立enum類型就簡單的多了.spa
public enum EnumMonth { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC; }
public class Main { public static void main(String[] args) { System.out.println(EnumMonth.APR);//APR } }
這樣聲明一個只有12個月份的類是否是簡單的多.並且咱們能夠看出.在客戶端咱們直接打印enum項打印的值,而不是地址值.那麼這裏邊究竟是怎麼實現的呢?咱們來看看反編譯後的enum3d
public final class EnumMonth extends Enum { public static final EnumMonth JAN; public static final EnumMonth FEB; public static final EnumMonth MAR; public static final EnumMonth APR; public static final EnumMonth MAY; public static final EnumMonth JUN; public static final EnumMonth JUL; public static final EnumMonth AUG; public static final EnumMonth SEP; public static final EnumMonth OCT; public static final EnumMonth NOV; public static final EnumMonth DEC; private static final EnumMonth $VALUES[]; public static EnumMonth[] values() { return (EnumMonth[])$VALUES.clone(); } public static EnumMonth valueOf(String name) { return (EnumMonth)Enum.valueOf(demo7/EnumMonth, name); } private EnumMonth(String s, int i) { super(s, i); } static { JAN = new EnumMonth("JAN", 0); FEB = new EnumMonth("FEB", 1); MAR = new EnumMonth("MAR", 2); APR = new EnumMonth("APR", 3); MAY = new EnumMonth("MAY", 4); JUN = new EnumMonth("JUN", 5); JUL = new EnumMonth("JUL", 6); AUG = new EnumMonth("AUG", 7); SEP = new EnumMonth("SEP", 8); OCT = new EnumMonth("OCT", 9); NOV = new EnumMonth("NOV", 10); DEC = new EnumMonth("DEC", 11); $VALUES = (new EnumMonth[] { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }); } }
從這個class文件咱們能看出code
EnumMonth繼承自Enum.對象
EnumMonth有一個私有的兩個參數的構造函數.blog
EnumMonth類中的枚舉項也是本身經過實例化的構成的.繼承
接下來咱們來看看他的兩個方法 valueOf() 和values()索引
public class Main { public static void main(String[] args) { System.out.println(EnumMonth.APR);//APR EnumMonth apr = EnumMonth.valueOf("APR"); System.out.println(apr);//APR EnumMonth[] values = EnumMonth.values();//JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC, for (EnumMonth enumMonth : values){ System.out.print(enumMonth+","); } } }
這不是咱們的重點,如今咱們要找它的toString()方法,可讓枚舉項直接打印出值的,確定只有toString().前往父類Enum尋找
因此如今能夠得出結論.當咱們建立一個枚舉類時,其實是有一個兩個參數構造函數.默認傳遞的實參是咱們的枚舉項字符串和索引.
那麼,若是咱們覆蓋雙參數的構造函數呢?
public enum DoubleEnumMonth { JAN("JAN",0), FEB("FEB",1), MAR("MAR",2); private DoubleEnumMonth(String a, int b) { } }
public class Main { public static void main(String[] args) { System.out.println(DoubleEnumMonth.JAN);//JAN } }
能夠看出,咱們雖然只聲明瞭雙參數的構造子,並無聲明屬性,也沒有this賦值,可是依然能夠經過toString()的方式直接訪問到屬性值.那確定是編譯器幫咱們調用了super(a,b);來看一下
public final class DoubleEnumMonth extends Enum { public static final DoubleEnumMonth JAN; public static final DoubleEnumMonth FEB; public static final DoubleEnumMonth MAR; private static final DoubleEnumMonth $VALUES[]; public static DoubleEnumMonth[] values() { return (DoubleEnumMonth[])$VALUES.clone(); } public static DoubleEnumMonth valueOf(String name) { return (DoubleEnumMonth)Enum.valueOf(demo7/DoubleEnumMonth, name); } private DoubleEnumMonth(String s, int i, String a, int b) { super(s, i); } static { JAN = new DoubleEnumMonth("JAN", 0, "JAN", 0); FEB = new DoubleEnumMonth("FEB", 1, "FEB", 1); MAR = new DoubleEnumMonth("MAR", 2, "MAR", 2); $VALUES = (new DoubleEnumMonth[] { JAN, FEB, MAR }); } }
這個結果,既有些意外之中,又意料以外.編譯器,幫咱們作了一個4個參數的構造函數.不用說前兩個確定仍是name和index.至於後兩個纔是咱們本身賦的值.
最後總結下.java的enum類型,自1.5出現後,就是爲了簡化咱們建立一個集合類的不可改變類的.