溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

java的枚舉是什么意思

發(fā)布時間:2021-08-18 10:56:32 來源:億速云 閱讀:197 作者:chen 欄目:編程語言

這篇文章主要介紹“java的枚舉是什么意思”,在日常操作中,相信很多人在java的枚舉是什么意思問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java的枚舉是什么意思”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

Tiger 中的一個重要新特性是枚舉構(gòu)造,它是一種新的類型,允許用常量來表示特定的數(shù)據(jù)片斷,而且全部都以類型安全的形式來表示。Tiger 專家、developerWorks 的多產(chǎn)作者 Brett McLaughlin將解釋枚舉的定義,介紹如何在應(yīng)用程序中運用枚舉,以及它為什么能夠讓您拋棄所有舊的public static final 代碼。

您已經(jīng)知道,Java 代碼的兩個基本的構(gòu)造塊是類 和接口。現(xiàn)在 Tiger 又引入了枚舉,一般簡稱它為 enum。這個新類型允許您表示特定的數(shù)據(jù)點,這些數(shù)據(jù)點只接受分配時預(yù)先定 義的值集合。
當(dāng)然,熟練的程序員可以用靜態(tài)常量實現(xiàn)這項功能,如清單 1 所示:

清單 1. public static final

public class OldGrade {  public static final int A = 1;  public static final int B = 2;  public static final int C = 3;  public static final int D = 4;  public static final int F = 5;  public static final int INCOMPLETE = 6;  }

說明:我要感謝 O'Reilly 媒體公司,該公司允許在本文中使用我撰寫的 Java 1.5 Tiger:A Developer's Notebook 一書中“枚舉”這一章中的代碼示例(請參閱參考資料)。

然后您就可以讓類接受像 OldGrade.B 這樣的常量,但是在這樣做的時候,請記住這類常量是 Java 中 int 類型的常量,這意味著該方法可以接受任何 int 類型的值,即使它和OldGrade 中定的所有級別都不對應(yīng)。因此,您需要檢測上界和下界,在出現(xiàn)無效值的時候,可能還要包含一個 IllegalArgumentException。而且,如果后來又添加另外一個級別(例如OldGrade.WITHDREW_PASSING),那么必須改變所有代碼中的上界,才能接受這個新值。

換句話說,在使用這類帶有整型常量的類時,該解決方案也許可行,但并不是非常有效。幸運的是,枚舉提供了更好的方法。

定義枚舉

清單 2 使用了一個可以提供與清單 1 相似的功能的枚舉:

清單 2. 簡單的枚舉類型

package com.oreilly.tiger.ch03;  public enum Grade   {  A, B, C, D, F, INCOMPLETE  };

在這里,我使用了新的關(guān)鍵字 enum,為 enum 提供了一個名稱,并指定了允許的值。然后
,Grade 就變成了一個枚舉類型,您可以按清單 3 所示的方法使用它:

清單 3. 使用枚舉類型

package com.oreilly.tiger.ch03;  public class Student {  private String firstName;  private String lastName;  private Grade grade;  public Student(String firstName, String lastName) {  this.firstName = firstName;  this.lastName = lastName;  }  public void setFirstName(String firstName) {  this.firstName = firstName;  }  public String getFirstName() {  return firstName;  }  public void setLastName(String lastName) {  this.lastName = lastName;  }  public String getLastName() {  return lastName;  }  public String getFullName() {  return new StringBuffer(firstName)  .append(" ")  .append(lastName)  .toString();  }  public void assignGrade(Grade grade) {  this.grade = grade;  }  public Grade getGrade() {  return grade;  }  }

用以前定義過的類型建立一個新的枚舉(grade)之后,您就可以像使用其他成員變量一樣使用它了。當(dāng)然,枚舉只能分配枚舉值中的一個(例如,A、C 或 INCOMPLETE)。而且,在assignGrade() 中是沒有進(jìn)行錯誤檢測的代碼,也沒有考慮邊界情況,請注意這是如何做到。

使用枚舉值

迄今為止,您所看到的示例都相當(dāng)簡單,但是枚舉類型提供的東西遠(yuǎn)不止這些。您可以逐個遍歷枚舉值,也可以在 switch 語句中使用枚舉值,枚舉是非常有價值的。

遍歷枚舉值

下面我們用一個示例顯示如何遍歷枚舉類型的值。清單 4 所示的這項技術(shù),適用于調(diào)試、快速打印任務(wù)以及把枚舉加載到集合(我很快將談到)中的工具:

清單 4. 遍歷枚舉值

public void listGradeValues(PrintStream out) throws IOException {  for (Grade g : Grade.values()) {  out.println("Allowed value: '" + g + "'");  }  }

運行這段代碼,將得到清單 5 所示的輸出:

清單 5. 迭代操作的輸出

Allowed Value: 'A'  Allowed Value: 'B'  Allowed Value: 'C'  Allowed Value: 'D'  Allowed Value: 'F'  Allowed Value: 'INCOMPLETE'

這里有許多東西。首先,我使用了 Tiger 的新的 for/in 循環(huán)(也叫作 foreach 或 增強(qiáng)的 for)。另外,您可以看到 values() 方法返回了一個由獨立的 Grade 實例構(gòu)成的數(shù)組,每個數(shù)組都有一個枚舉類型的值。換句話說,values() 的返回值是 Grade[]。

在枚舉間切換

能夠在枚舉的值之間移動很好,但是更重要的是根據(jù)枚舉的值進(jìn)行決策。您當(dāng)然可以寫一堆if (grade.equals(Grade.A)) 類型的語句,但那是在浪費時間。Tiger 能夠很方便地把枚舉支持添加到過去的好東西 switch 語句上,所以它很容易使用,而且適合您已知的內(nèi)容。

清單 6 向?qū)⒄故救绾谓鉀Q這個難題:

清單 6. 在枚舉之間切換

public void testSwitchStatement(PrintStream out) throws IOException {  StringBuffer outputText = new StringBuffer(student1.getFullName());  switch (student1.getGrade()) {  case A:  outputText.append(" excelled with a grade of A");  break;  case B: // fall through to C  case C:  outputText.append(" passed with a grade of ")  .append(student1.getGrade().toString());  break;  case D: // fall through to F  case F:  outputText.append(" failed with a grade of ")  .append(student1.getGrade().toString());  break;  case INCOMPLETE:  outputText.append(" did not complete the class.");  break;  }  out.println(outputText.toString());  }

在這里,枚舉值被傳遞到 switch 語句中(請記住,getGrade() 是作為 Grade 的實例返回的),而每個 case 子句將處理一個特定的值。該值在提供時沒有枚舉前綴,這意味著不用將代碼寫成 case Grade.A,只需將其寫成 case A 即可。如果您不這么做,編譯器不會接受有前綴的值。

現(xiàn)在,您應(yīng)該已經(jīng)了解使用 switch 語句時的基本語法,但是還有一些事情您需要知道。在使用 switch 之前進(jìn)行計劃
正如您所期待的,在使用枚舉和 switch 時,您可以使用 default 語句。清單 7 顯示了這個用法:

清單 7. 添加一個 default 塊

public void testSwitchStatement(PrintStream out) throws IOException {  StringBuffer outputText = new StringBuffer(student1.getFullName());  switch (student1.getGrade()) {  case A:  outputText.append(" excelled with a grade of A");  break;  case B: // fall through to C  case C:  outputText.append(" passed with a grade of ")  .append(student1.getGrade().toString());  break;  case D: // fall through to F  case F:  outputText.append(" failed with a grade of ")  .append(student1.getGrade().toString());  break;  case INCOMPLETE:  outputText.append(" did not complete the class.");  break;  default:  outputText.append(" has a grade of ")  .append(student1.getGrade().toString());  break;  }  out.println(outputText.toString());  }

研究以上代碼可以看出,任何沒有被 case 語句處理的枚舉值都會被 default 語句處理。這項技術(shù)您應(yīng)當(dāng)堅持采用。原因是:假設(shè) Grade 枚舉被您的小組中其他程序員修改(而且他忘記告訴您這件事)成清單 8 所示的版本:

清單 8. 給 Grade 枚舉添加一個值

package com.oreilly.tiger.ch03;  public enum Grade {  A, B, C, D, F, INCOMPLETE,  WITHDREW_PASSING, WITHDREW_FAILING  };

現(xiàn)在,如果使用清單 6 的代碼所示的新版 Grade,那么這兩個新值會被忽略。更糟的是,您甚至看不到錯誤!在這種情況下,存在某種能夠通用的 default 語句是非常重要的。清單 7 無法很好地處理這些值,但是它會提示您還有其他值,您需要處理這些值。一旦完成處理,您就會有一個繼續(xù)運行的應(yīng)用程序,而且它不會忽略這些值,甚至還會指導(dǎo)您下一步的動作。所以這是一個良好的編碼習(xí)慣。

枚舉和集合

您所熟悉的使用 public static final 方法進(jìn)行編碼的那些東西,可能已經(jīng)轉(zhuǎn)而采用枚舉的值作為映射的鍵。如果您不知道其中的含義,請參見清單 9,它是一個公共錯誤信息的示例,在使用 Ant 的 build 文件時,可能會彈出這樣的消息,如下所示:

清單 9. Ant 狀態(tài)碼

package com.oreilly.tiger.ch03;  public enum AntStatus {  INITIALIZING,  COMPILING,  COPYING,  JARRING,  ZIPPING,  DONE,  ERROR  }

為每個狀態(tài)碼分配一些人們能讀懂的錯誤信息,從而允許人們在 Ant 提供某個代碼時查找合適的錯誤信息,將這些信息顯示在控制臺上。這是映射(Map)的一個絕好用例,在這里,每個映射(Map)的鍵都是一個枚舉值,而每個值都是鍵的錯誤信息。清單 10 演示了該映射的工作方式:

清單 10. 枚舉的映射(Map)

public void testEnumMap(PrintStream out) throws IOException {  // Create a map with the key and a String message  EnumMap<AntStatus, String> antMessages =  new EnumMap<AntStatus, String>(AntStatus.class);  // Initialize the map  antMessages.put(AntStatus.INITIALIZING, "Initializing Ant...");  antMessages.put(AntStatus.COMPILING, "Compiling Java classes...");  antMessages.put(AntStatus.COPYING, "Copying files...");  antMessages.put(AntStatus.JARRING, "JARring up files...");  antMessages.put(AntStatus.ZIPPING, "ZIPping up files...");  antMessages.put(AntStatus.DONE, "Build complete.");  antMessages.put(AntStatus.ERROR, "Error occurred.");  // Iterate and print messages  for (AntStatus status : AntStatus.values() ) {  out.println("For status " + status + ", message is: " +  antMessages.get(status));  }  }

該代碼使用了泛型(generics)(請參閱參考資料)和新的 EnumMap 構(gòu)造來建立新映射。而且,枚舉值是通過其 Class 對象提供的,同時提供的還有映射值的類型(在該例中,它只是一個簡單的字符串)。該方法的輸出如清單 11 所示:

枚舉的 Class 對象

您可能已經(jīng)注意到,清單 10 中的示例代碼實際上表明 Tiger 把枚舉當(dāng)作類,這可以從AntStatus 的 Class 對象那里得到證明,該對象不僅可用,而且正被實際使用。這是真的。歸根到底, Tiger 還是把枚舉看成是特殊的類類型。有關(guān)枚舉的具體實現(xiàn)細(xì)節(jié),請參閱Java 5.0 Tiger: A Developer's Notebook 的第三章(請參閱參考資料)。

清單 11. 清單 10 的輸出

[echo] Running AntStatusTester...  [java] For status INITIALIZING, message is: Initializing Ant...  [java] For status COMPILING, message is: Compiling Java classes...  [java] For status COPYING, message is: Copying files...  [java] For status JARRING, message is: JARring up files...  [java] For status ZIPPING, message is: ZIPping up files...  [java] For status DONE, message is: Build complete.  [java] For status ERROR, message is: Error occurred.

更進(jìn)一步枚舉也可以與集合結(jié)合使用,而且非常像新的 EnumMap 構(gòu)造,Tiger 提供了一套新的EnumSet實現(xiàn),允許您使用位操作符。另外,可以為枚舉添加方法,用它們實現(xiàn)接口,定義叫作特定值的類的實體,在該實體中,特定的代碼被附加到枚舉的具體值上。這些特性超出了本文的范圍,但是在其他地方,有詳細(xì)介紹它們的文檔(請參閱參考資料)。

使用枚舉,但是不要濫用

學(xué)習(xí)任何新版語言的一個危險就是瘋狂使用新的語法結(jié)構(gòu)。如果這樣做,那么您的代碼就會突然之間有 80% 是泛型、標(biāo)注和枚舉。所以,應(yīng)當(dāng)只在適合使用枚舉的地方才使用它。那么,枚舉在什么地方適用呢?一條普遍規(guī)則是,任何使用常量的地方,例如目前用 switch代碼切換常量的地方。如果只有單獨一個值(例如,鞋的***尺寸,或者籠子中能裝猴子的***數(shù)目),則還是把這個任務(wù)留給常量吧。但是,如果定義了一組值,而這些值中的任何一個都可以用于特定的數(shù)據(jù)類型,那么將枚舉用在這個地方最適合不過。

到此,關(guān)于“java的枚舉是什么意思”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI