java 枚舉的學習和使用

最近在看別人的代碼的時候,經常會看到有使用到枚舉的地方,但是在自己寫的時候,也有想到過用枚舉,但是對什麼時候使用枚舉和 常量 沒有一個明確的概念,比較模糊。所以特別整理了一下有關枚舉的知識,以供學習使用。

1.什麼java 的枚舉類型

以我的理解答:枚舉是我們自己定義的一個集合,比如說我們數學裏面所學的集合A={1、2、3},當我們要使用A這個集合的時候,我們只能夠使用集合A裏面的1、2、3這三個元素,不是A裏面的元素我們就不可以使用。
同樣,枚舉和這個集合是類似的,當我們定義了一個枚舉類型的時候,我們聲明它裏面有幾個元素,在我們使用這個枚舉的時候,我們只能夠使用它有的元素,沒有的元素我們是無法使用,系統就會報錯!
枚舉還有一個特點,就是可以代表數值,比如說第一個定義的元素對應的值爲0,每個枚舉元素從0開始,逐一增加。此時,這個數值也代表他們本身,相當於每一個元素有兩個名字。

2.什麼情況下使用枚舉類型

2.1 什麼情況下使用枚舉類?
  有的時候一個類的對象是有限且固定的,這種情況下我們使用枚舉類就比較方便.
  
2.2 爲什麼不用靜態常量來替代枚舉類呢?

   public static final int SEASON_SPRING = 1;
  public static final int SEASON_SUMMER = 2;
  public static final int SEASON_FALL = 3;
  public static final int SEASON_WINTER = 4;

 枚舉類更加直觀,類型安全。使用常量會有以下幾個缺陷:
  1. 類型不安全。若一個方法中要求傳入季節這個參數,用常量的話,形參就是int類型,開發者傳入任意類型的int類型值就行,但是如果是枚舉類型的話,就只能傳入枚舉類中包含的對象。
  2. 沒有命名空間。開發者要在命名的時候以SEASON_開頭,這樣另外一個開發者再看這段代碼的時候,才知道這四個常量分別代表季節。

2.3 常使用的地方:
我們要從另一個函數得到一個值,但是這個值只能夠在一個範圍內的,此時我們就可以使用枚舉來定義這個範圍。限制另外一個函數能夠傳遞進來的值,只能夠是枚舉類型裏面的元素

3.枚舉類的簡單使用和注意點

package enumcase;
  public enum SeasonEnum {
  SPRING,SUMMER,FALL,WINTER;
  }

然後可以這樣來使用:SeasonEnum currentSeason = SeasonEnum .SUMMER

注意:
(1) enum和class、interface的地位一樣
(2) 使用enum定義的枚舉類默認繼承了java.lang.Enum,而不是繼承Object類。枚舉類可以實現一個或多個接口。
(3) 枚舉類的所有實例都必須放在第一行展示,不需使用new 關鍵字,不需顯式調用構造器。自動添加public static final修飾。
(4) 使用enum定義、非抽象的枚舉類默認使用final修飾,不可以被繼承。
(5) 枚舉類的構造器只能是私有的。

3.1枚舉類內也可以定義屬性和方法,可是是靜態的和非靜態的。

package enumcase;
  public enum SeasonEnum {
      SPRING("春天"),
      SUMMER("夏天"),
      FALL("秋天"),
      WINTER("冬天");
  
  private final String name;
  
  private SeasonEnum(String name)
  {
     this.name = name;
  }
  public String getName() {
    return name;
  }
 }

實際上在第一行寫枚舉類實例的時候,默認是調用了構造器的,所以此處需要傳入參數,因爲沒有顯式申明無參構造器,只能調用有參數的構造器。
  構造器需定義成私有的,這樣就不能在別處申明此類的對象了。枚舉類通常應該設計成不可變類,它的Field不應該被改變,這樣會更安全,而且代碼更加簡潔。所以我們將Field用private final修飾。

3.2 枚舉類遍歷
枚舉類型提供了兩個有用的靜態方法 values( ) 和 valueOf( ) 我們可以很方便的使用它們
例如:

 for(SeasonEnum s : SeasonEnum .values())
     System.out.println(s);

3.3 switch語句裏的表達式可以是枚舉值

package enumcase;
public class SeasonTest {
 public void judge(SeasonEnum s){
  switch(s){
      case SPRING:
        System.out.println("春天適合踏青。");
      break;
      case SUMMER:
        System.out.println("夏天要去游泳啦。");
      break;
      case FALL:
        System.out.println("秋天一定要去旅遊哦。");
      break;
      case WINTER:
        System.out.println("冬天要是下雪就好啦。");
      break;
  }
 }
 
public static void main(String[] args) {
  SeasonEnum s = SeasonEnum.SPRING;
  SeasonTest test = new SeasonTest();
  test.judge(s);
  }
}

3.4 定義枚舉類型時本質上就是定義一個類別,只不過很多細節由編譯器幫我們完成了,所以某些程度上,enum關鍵字的作用 就像是class或interface

3.5 使用enum定義的枚舉類默認繼承了java.lang.Enum,而不是繼承Object類

當我們使用“enum”定義枚舉類型時,實質上我們定義出來的類型繼承自java.lang.Enum類型,而枚舉的成員其實就是我們定義的枚舉類型的一個實例(Instance),他們都被預設爲final,所以我們無法改變他們,他們也是static成員,所以我們可以通過類型名稱直接使用他們,當然最重要的,他們都是公開的(public)。即,我們定義的每個枚舉類型都繼承自java.lang.Enum類,枚舉中的每一個成員默認都是public static final 的。
而每個枚舉的成員其實就是我們定義的枚舉類型的一個實例(Instance)。換句話說,當定義了一個枚舉類型後,在編譯時刻就能確定該枚舉類型有幾個實例,分別是什麼。在運行期間我們無法再使用該枚舉類型創建新的實例了,這些實例在編譯期間就已經完全確定下來了。 所以在:SeasonEnum currentSeason = SeasonEnum .SUMMER 中,沒有new SeasonEnum ()。而是直接賦值

3.6 檢查權限

如一個經理、員工、顧客對一個工具的使用權限,一般用枚舉來處理 因爲這樣子可以用來控制傳入判斷的參數只能夠是該枚舉類型的數,從而限制傳入的參數.

package Enum;

public class AccessControl {
    public static boolean checkRight(AccessRight access){
        if(access == AccessRight.MANAGER){
            return true;
        }
        else if(access == AccessRight.DEPARMENT){
           return false;
        }else {
          return false;
        }

    public static void main(String[] args) {
        System.out.println(checkRight(AccessRight.DEPARMENT));
    }
}

enum AccessRight{
MANAGER,DEPARMENT,EMPLOYEE;

通過這樣,只能夠傳遞AccessRight類型的參數,其他參數都是不合法的。

3.7 將String類型轉換爲枚舉類型

static <T extends Enum<T>> T 
valueOf(Class<T> enumType, String name) 

返回帶指定名稱的指定枚舉類型的枚舉常量。

可以這樣子使用 AccessRight access = AccessRight.valueOf(“MANAGER”);//只要AccessRight中有MANAGER的元素就可以返回這個元素,即將String類型轉換爲AccessRight類型

4.參考的網站

至此枚舉學習了很多,對於網上的一些東西稍微整理,下面我是我借鑑的一些網站

https://www.douban.com/note/512891241/
http://blog.sina.com.cn/s/blog_4adc4b090101dtxp.html
http://blog.sina.com.cn/s/blog_697b968901013ih1.html

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