瘋狂Java之學習筆記(25)-------------修飾符">瘋狂Java之學習筆記(25)-------------修飾符
867
2025-03-31
瘋狂Java之學習筆記(30)------------枚舉
Java5 枚舉類型使用總結(jié)
一、概述
枚舉在什么地方適用呢?一條普遍規(guī)則是,任何使用常量的地方,例如目前用 switch 代碼切換常量的地方。如果只有單獨一個值(例如,鞋的最大尺寸,或者籠子中能裝猴子的最大數(shù)目),則還是把這個任務留給常量吧。但是,如果定義了一組值,而這些值中的任何一個都可以用于特定的數(shù)據(jù)類型,那么將枚舉用在這個地方最適合不過。
二、在枚舉類型之前,Java是如何實現(xiàn)枚舉功能的
在枚舉類型出現(xiàn)之前,java是通過在接口或者類中定義public static final 的變量來實現(xiàn)的。比如,對于經(jīng)典的紅色警戒2中的英國狙擊(sharp-shooter)手三個動作的描述:
/**
public?interface?SharpShooter_1 {
public?static?final?int?LOCKED = 1;?????//鎖定
public?static? final? int?AIM = 2;???????? //瞄準
public? static? final? int?SHOOT = 3;?????? //射擊
}
/**
public?class?TestDemo_1 {
public?static?void?main(String args[]) {
TestDemo_1 test =?new?TestDemo_1();
test.doAction(1);
test.doAction(2);
test.doAction(3);
test.doAction(4);
}
/**
public?void?doAction(int?action) {
switch?(action) {
case?SharpShooter_1.LOCKED:
System.out.println("1:鎖定目標");
break;
case?SharpShooter_1.AIM:
System.out.println("2:瞄準目標");
break;
case?SharpShooter_1.SHOOT:
System.out.println( "3:射擊");
break;
default:
System.out.println( "×:游戲還沒有定義此動作!");
}
}
}
運行結(jié)果:
1:鎖定目標
2:瞄準目標
3:射擊
×:游戲還沒有定義此動作!
[說明]:當然SharpShooter_1也可以聲明為class,還可以直接將常量定義到TestDemo_1中,如果常量只是在類內(nèi)部使用,就聲明為private或者是protected,如果聲明為public,則通常是與類功能相聯(lián)系的常數(shù)。
[注意]:switch語句的條件只能接收數(shù)值或字符(byte、short、int或char)或枚舉(enum)類型的變量名或表達式。如果沒有符合條件數(shù)值或字符,則執(zhí)行default語句,default語句不是必須的,如果沒有默認要處理的動作,則default語句可省略。break語句的作用是跳出循環(huán)塊。
三、枚舉類型的等價實現(xiàn)
/**
public?enum?SharpShooter_2 {
LOCKED,
AIM,
SHOOT
}
/**
public?class?TestDemo_2 {
public?static?void?main(String args[]){
TestDemo_2 test=new?TestDemo_2();
test.doAction(SharpShooter_2.LOCKED);
test.doAction(SharpShooter_2.AIM);
test.doAction(SharpShooter_2.SHOOT);
}
/**
public?void?doAction(SharpShooter_2 action) {
switch?(action) {
case?LOCKED:
System.out.println("1:鎖定目標");
break;
case?AIM:
System.out.println("2:瞄準目標");
break;
case?SHOOT:
System.out.println( "3:射擊");
break;
default:
System.out.println( "×:游戲還沒有定義此動作!");
}
}
}
運行結(jié)果:
1:鎖定目標
2:瞄準目標
3:射擊
三、枚舉類型的實質(zhì)
在編譯SharpShooter_2.java后,會生成一個SharpShooter_2.class文件,這說明枚舉類型的實質(zhì)還是一個類。因此,在某種程度上,enum關(guān)鍵字的作用就是class或者interface。
當使用enum定義一個枚舉類型時,實際上所定義的類型自動繼承了java.lang.Enum類。而每個被枚舉的成員實質(zhì)就是一個枚舉類型的實例,他們默認都是public static final的。可以直接通過枚舉類型名直接使用它們。
在查詢JDK1.5文檔的java.lang.Enum類,里面清楚的說明:java.lang.Enum類是所有 Java 語言枚舉類型的公共基本類。因此,所有枚舉類型都擁有有java.lang.Enum類所提供的共有方法。因此,要學會使用枚舉,還必須認識java.lang.Enum類。下面將詳細說明。
四、java.lang.Enum類
public abstract class Enum
------------------
構(gòu)造方法摘要
protected Enum(String name,int ordinal)
單獨的構(gòu)造方法。程序員無法調(diào)用此構(gòu)造方法。該構(gòu)造方法用于由響應枚舉類型聲明的編譯器發(fā)出的代碼。
參數(shù):
name - - 此枚舉常量的名稱,它是用來聲明該常量的標識符。
ordinal - - 枚舉常量的序數(shù)(它在枚舉聲明中的位置,其中初始常量序數(shù)為零)。
------------------
方法摘要
protected? Object clone()
拋出 CloneNotSupportedException。
int compareTo(E o)
比較此枚舉與指定對象的順序。在該對象小于、等于或大于指定對象時,分別返回負整數(shù)、零或正整數(shù)。 枚舉常量只能與相同枚舉類型的其他枚舉常量進行比較。該方法實現(xiàn)的自然順序就是聲明常量的順序。
boolean equals(Object other)
當指定對象等于此枚舉常量時,返回 true。
Class
返回與此枚舉常量的枚舉類型相對應的 Class 對象。當且僅當 e1.getDeclaringClass() == e2.getDeclaringClass() 時,兩個枚舉常量 e1 和 e2 的枚舉類型才相同。(由該方法返回的值不同于由 Object.getClass() 方法返回的值,Object.getClass() 方法用于帶有特定常量的類主體的枚舉常量。)
int hashCode()
返回枚舉常量的哈希碼。
String name()
返回此枚舉常量的名稱,在其枚舉聲明中對其進行聲明。 與此方法相比,大多數(shù)程序員應該優(yōu)先考慮使用 toString() 方法,因為 toString 方法返回更加用戶友好的名稱。該方法主要設(shè)計用于特殊情形,其正確性取決于獲得正確的名稱,其名稱不會隨版本的改變而改變
int ordinal()
返回枚舉常量的序數(shù)(它在枚舉聲明中的位置,其中初始常量序數(shù)為零)。 大多數(shù)程序員不會使用此方法。它被設(shè)計用于復雜的基于枚舉的數(shù)據(jù)結(jié)構(gòu),比如 EnumSet 和 EnumMap。
String toString()
返回枚舉常量的名稱,它包含在聲明中。
public static
返回帶指定名稱的指定枚舉類型的枚舉常量。名稱必須與在此類型中聲明枚舉常量所用的標識符完全匹配。(不允許使用額外的空白字符。)
參數(shù):
enumType - 要從中返回常量的枚舉類型的 Class 對象
name - 要返回的常量名稱
注意:ordinal() 方法得到枚舉順序的索引,默認從0開始。
五、枚舉的高級用法
1、枚舉方法
既然枚舉的本質(zhì)是類,那么定義枚舉類型時也可以定義方法。比如:
/**
public?enum?SharpShooter_3 {
LOCKED,
AIM,
SHOOT;
public?String getDesc() {
switch?(this.ordinal()) {
case?0:
return?"鎖定目標";
case?1:
return? "瞄準目標";
case?2:
return? "射擊";
default:
return? "沒有該枚舉值!";
}
}
}
/**
public?class?TestDemo_3 {
public?static?void?main(String args[]) {
for?(SharpShooter_3 enumSS : SharpShooter_3.values()) {
System.out.println(enumSS +?" "?+ enumSS.getDesc());
}
}
}
運行結(jié)果:
LOCKED 鎖定目標
AIM 瞄準目標
SHOOT 射擊
Process finished with exit code 0
2、枚舉構(gòu)造方法
/**
public?enum?SharpShooter_4 {
LOCKED("鎖定目標"),
AIM("瞄準目標"),
SHOOT("射擊");
private?String desc;????????//枚舉說明
/**
private?SharpShooter_4(String desc){
this.desc=desc;
}
/**
public?String getDesc(){
return?desc;
}
}
/**
public?class?TestDemo_4 {
public?static?void?main(String args[]) {
for?(SharpShooter_4 enumSS : SharpShooter_4.values()) {
System.out.println(enumSS +?" "?+ enumSS.getDesc());
}
}
}
運行結(jié)果:
LOCKED 鎖定目標
AIM 瞄準目標
SHOOT 射擊
Process finished with exit code 0
3、實現(xiàn)接口的枚舉
/**
public?interface?IDesc {
/**
public?String getDesc();
}
/**
public?enum?SharpShooter_5?implements?IDesc {
LOCKED("鎖定目標"),
AIM("瞄準目標"),
SHOOT("射擊");
private?String desc;????????//枚舉說明
/**
private?SharpShooter_5(String desc) {
this.desc = desc;
}
public?String getDesc() {
return?desc;
}
}
/**
public?class?TestDemo_5 {
public?static?void?main(String args[]) {
for?(SharpShooter_5 enumSS : SharpShooter_5.values()) {
System.out.println(enumSS +?" "?+ enumSS.getDesc());
}
}
}
運行結(jié)果:
LOCKED 鎖定目標
AIM 瞄準目標
SHOOT 射擊
Process finished with exit code 0
4、每個枚舉值實現(xiàn)的自己的接口
/**
public?enum?SharpShooter_6?implements?IDesc {
LOCKED(){
public?String getDesc() {
return?"鎖定目標";
}
},
AIM{
public?String getDesc() {
return?"瞄準目標";
}
},
SHOOT{
public?String getDesc() {
return? "射擊";
}
}
}
/**
public?class?TestDemo_6 {
public?static?void?main(String args[]) {
for?(SharpShooter_6 enumSS : SharpShooter_6.values()) {
System.out.println(enumSS +?" "?+ enumSS.getDesc());
}
}
}
運行結(jié)果:
LOCKED 鎖定目標
AIM 瞄準目標
SHOOT 射擊
Process finished with exit code 0
5、帶有抽象方法的枚舉類型
/**
public?enum?SharpShooter_7 {
LOCKED(){
public?String getDesc() {
return?"鎖定目標";
}
},
AIM{
public?String getDesc() {
return?"瞄準目標";
}
},
SHOOT{
public?String getDesc() {
return? "射擊";
}
};
/**
public?abstract?String getDesc();
}
/**
public?class?TestDemo_7 {
public?static?void?main(String args[]) {
for?(SharpShooter_7 enumSS : SharpShooter_7.values()) {
System.out.println(enumSS +?" "?+ enumSS.getDesc());
}
}
}
運行結(jié)果:
LOCKED 鎖定目標
AIM 瞄準目標
SHOOT 射擊
Process finished with exit code 0
六、對Java枚舉類型的一些看法
枚舉的本質(zhì)是類,在沒有枚舉之前,仍然可以按照java最基本的編程手段來解決需要用到枚舉的地方。枚舉屏蔽了枚舉值的類型信息,不像在用public static final定義變量必須指定類型。枚舉是用來構(gòu)建常量數(shù)據(jù)結(jié)構(gòu)的模板,這個模板可擴展。枚舉的使用增強了程序的健壯性,比如在引用一個不存在的枚舉值的時候,編譯器會報錯。枚舉的更多用法還需要在開發(fā)中去研究創(chuàng)造,Java5、Java6增加了不少新的特性,技術(shù)在升級,對程序員來說就要學習,如果你熱愛java的話。否則別人用到新特性的代碼你看不懂,那才叫郁悶。
目前,本人在開發(fā)中也很少用到枚舉,雖然Java設(shè)計得很好,處心積慮為開發(fā)人員著想,但是是否有必要增加一個關(guān)鍵字讓全世界的java程序員去學習研究?本人感覺Java現(xiàn)在越來越復雜了,新特性對我而言是一大障礙,需要大量的時間去熟悉?對此,我也不敢妄下結(jié)論,一是我們和java科學家差距太大,二是怕誤導讀者,這個就留個各位讀者吧!
參考http://lavasoft.blog.51cto.com/62575/45921/
轉(zhuǎn)載自:https://blog.csdn.net/u011225629/article/details/45675765
Java 開發(fā)者
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。