Junit單元測試遇見的一個枚舉類型的坑(枚舉類型詳解) 原

Enum的簡介

Enum是計算機編程語言中的一種數據類型。枚舉類型

枚舉類型很早就在計算機語言中存在了,主要被用來將一組相似的值包含進一種類型中,這種類型的名稱被定義成獨一無二的類型描述符,這就是枚舉類型。

在java語言中,枚舉類型是一個完整功能的類,允許開發者給枚舉類型添加方法和屬性,同時也可以提供接口。同時Java也爲Enum提供了高質量的實現,比如comparable和Serializable接口.

  • 其中:Comparable 是排序接口,如果一個Java類有這個接口,那麼只能說明這個類支持排序。即然實現Comparable接口的類支持排序,假設現在存在“實現Comparable接口的類的對象的List列表(或數組),則該List列表(或數組)可以通過 Collections.sort(或 Arrays.sort)進行排序。“實現Comparable接口的類的對象”可以用作“有序映射(如TreeMap)”中的鍵或“有序集合(TreeSet)”中的元素,而不需要指定比較器。 Serializable接口的對象轉換成一個字符序列,並能夠在以後將這個字節序列完全恢復爲原來的對象。而且這個過程是可以通過網絡完成的,也就是說序列化機制能夠自動彌補不同操作系統之間差異。*

Enum的定製

通過類的定義,可以給Enum一些複雜的功能,例如下面代碼給Enum增加屬性:

public enum DrinkEnum{

1.  // 酒

2.  Wine("a cup of wine ");

3.  //橙汁

4.  Oragen_Juice("a cup of oragen juice")

5.  //Enum對象的drink_class屬性

6.  private  String drink_class;

7.  //枚舉對象構造函數

8.  private  DrinkEnum(String drink){

9.  this.drink_class=drink;

10.  }

11.  //枚舉對象的drink_class屬性

12.  public  String getDrink(){

13.  return  this.drink_class;

14.  }

Enum的一些坑

  1. 1 Enum 不支持public和protected修飾符的構造方法,因此構造函數一定要是private或者friendly的,這也就約束了枚舉對象是無法在程序中通過直接調用構造函數進行初始化的。

  2. 2 Enum的值是通過運行期構造出來的對象表示的,因此在集羣環境下,每個jvm構造出同義對象,但是在做布爾運算的時候有可能有問題,因此要格外注意。在對Enum進行比較的時候,使用值比對。

Enum的原理

在使用enum創建枚舉類型後,編譯器會爲其生成一個對應的枚舉類,這個類繼承與java.lang.Enum。舉例如下:


1.  enum  Day  {

2.  MONDAY, TUESDAY, WEDNESDAY,

3.  THURSDAY, FRIDAY, SATURDAY, SUNDAY

4.  }

編譯後會變成Day.class,那麼反編譯後看到如下:

1.  final  class  Day  extends  Enum

2.  {

3.  //編譯器爲我們添加的靜態的values()方法

4.  public  static  Day[] values()

5.  {

6.  return  (Day[])$VALUES.clone();

7.  }

8.  //編譯器爲我們添加的靜態的valueOf()方法,注意間接調用了Enum也類的valueOf方法

9.  public  static  Day valueOf(String s)

10.  {

11.  return  (Day)Enum.valueOf(com/zejian/enumdemo/Day, s);

12.  }

13.  //私有構造函數

14.  private  Day(String s,  int i)

15.  {

16.  super(s, i);

17.  }

18.  //前面定義的7種枚舉實例

19.  public  static  final  Day MONDAY;

20.  public  static  final  Day TUESDAY;

21.  public  static  final  Day WEDNESDAY;

22.  public  static  final  Day THURSDAY;

23.  public  static  final  Day FRIDAY;

24.  public  static  final  Day SATURDAY;

25.  public  static  final  Day SUNDAY;

26.  private  static  final  Day $VALUES[];

27.  static

28.  { 

29.  //實例化枚舉實例

30.  MONDAY =  new  Day("MONDAY",  0);

31.  TUESDAY =  new  Day("TUESDAY",  1);

32.  WEDNESDAY =  new  Day("WEDNESDAY",  2);

33.  THURSDAY =  new  Day("THURSDAY",  3);

34.  FRIDAY =  new  Day("FRIDAY",  4);

35.  SATURDAY =  new  Day("SATURDAY",  5);

36.  SUNDAY =  new  Day("SUNDAY",  6);

37.  $VALUES =  (new  Day[]  {

38.  MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY

39.  });

40.  }

41.  }

可以看到,編譯後生成一個final類,同時前面的七個日期定義成七個類型。同時還有兩個靜態方法,分別是values()和 valueOf(),MONDAY枚舉類型對應public static final Day MONDAY;,values()方法的作用就是獲取枚舉類中的所有變量,並作爲數組返回,而valueOf(String name)方法與Enum類中的valueOf方法的作用類似根據名稱獲取枚舉變量,只不過編譯器生成的valueOf方法更簡潔些只需傳遞一個參數。由於values()方法是由編譯器插入到枚舉類中的static方法,所以如果我們將枚舉實例向上轉型爲Enum,那麼values()方法將無法被調用,因爲Enum類中並沒有values()方法,valueOf()方法也是同樣的道理。

final變量經常和static關鍵字一起使用,作爲常量。final類通常功能是完整的,不允許被繼承。

因此枚舉類型,在調用中如果對內部變量使用了set函數,那麼就是對一個常量進行了上set操作,也就會導致所有調用的地方的值都發生了變化。

如果對軟件測試、接口測試、自動化測試、性能測試、LR腳本開發、面試經驗交流。感興趣可以175317069,羣內會有不定期的發放免費的資料鏈接,這些資料都是從各個技術網站蒐集、整理出來的,如果你有好的學習資料可以私聊發我,我會註明出處之後分享給大家。

EnumSet和EnumMap

EnumSet

EnumSet是一個針對枚舉類型的高性能Set接口實現,但是在其中裝入的枚舉類型必須是同類型的,在EnumSet中通過bit-vector實現,也就是一個long型。EnumSet支持在遍歷。


1.  for  (WeekDayEnum day:EnumSet.range(WeekDayEnum.Mon,WeekDayEnum.Sun)){

2.  System.out.println(day)

3.  }

同時EnumSet還提供了一個獲取子集的方法:


1.  EnumSet  <WeekDayEnum>  JobDays  = EnumSet.of(WeekDayEnum.Mon,WeekDayEnum.Fri);

EnumMap

EnumMap是一個高性能的Map接口實現,主要管理用枚舉做Key-Value的關係,內部是通過數組方式實現的。


1.  private  static  Map<WeekDayEnum,RainbowClolor> schema =  new  EnumMap<WeekDayEnum.values()[i],RainbowClolor.values()[i]>(WeekDatEnum.class);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章