亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Effective Java (枚舉)

系統 2220 0

?

三十、用enum代替int常量:

?? ?? 枚舉類型是指由一組固定的常量組成合法值的類型,該特征是在Java 1.5 中開始被支持的,之前的Java代碼都是通過“公有靜態常量域字段”的方法來簡單模擬枚舉的,如:
? ? ? public static final int APPLE_FUJI = 0;
? ? ? public static final int APPLE_PIPPIN = 1;
? ? ? public static final int APPLE_GRANNY_SMITH = 2;
?? ?? ... ...
?? ?? public static final int ORANGE_NAVEL = 0;
? ? ? public static final int ORANGE_TEMPLE = 1;
? ? ? public static final int ORANGE_BLOOD = 2;
? ? ? 這樣的寫法是比較脆弱的。首先是沒有提供相應的類型安全性,如兩個邏輯上不相關的常量值之間可以進行比較或運算(APPLE_FUJI - ORANGE_TEMPLE),再有就是常量int是編譯時常量,被直接編譯到使用他們的客戶端中。如果與該常量關聯的int發生了變化,客戶端就必須重新編譯。如果沒有重新編譯,程序還是可以執行,但是他們的行為將不確定。
? ? ? 下面我們來看一下Java 1.5 中提供的枚舉的聲明方式:
? ? ? public enum Apple { FUJI, PIPPIN, GRANNY_SMITH }
? ? ? public enum Orange { NAVEL, TEMPLE, BLOOD }
? ? ? 和“公有靜態常量域字段”不同的是,如果函數的參數是枚舉類型,如Apple,那么他的實際值只能來自于該枚舉所聲明的枚舉值,即FUJI, PIPPIN, GRANNY_SMITH。如果試圖將Apple和Orange中的枚舉值進行比較,將會導致編譯錯誤。
? ? ? 和C/C++中提供的枚舉不同的是,Java中允許在枚舉中添加任意的方法和域,并實現任意的接口。下面先給出一個帶有域方法和域字段的枚舉聲明:

        
           1
        
        
          public
        
        
          enum
        
         Planet {

        
           2
        
                 MERCURY(3.302e+23,2.439e6),

        
           3
        
                 VENUS(4.869e+24,6.052e6),

        
           4
        
                 EARTH(5.975e+24,6.378e6),

        
           5
        
                 MARS(6.419e+23,3.393e6),

        
           6
        
                 JUPITER(1.899e+27,7.149e7),

        
           7
        
                 SATURN(5.685e+26,6.027e7),

        
           8
        
                 URANUS(8.683e+25,2.556e7),

        
           9
        
                 NEPTUNE(1.024e+26,2.477e7);

        
          10
        
        
          private
        
        
          final
        
        
          double
        
         mass;   
        
          //
        
        
          千克
        
        
        
        
          11
        
        
          private
        
        
          final
        
        
          double
        
         radius; 
        
          //
        
        
        
        
        
          12
        
        
          private
        
        
          final
        
        
          double
        
         surfaceGravity;

        
          13
        
        
          private
        
        
          static
        
        
          final
        
        
          double
        
         G = 6.67300E-11;

        
          14
        
                 Planet(
        
          double
        
         mass,
        
          double
        
         radius) {

        
          15
        
        
          this
        
        .mass = mass;

        
          16
        
        
          this
        
        .radius = radius;

        
          17
        
                     surfaceGravity = G * mass / (radius * radius);

        
          18
        
                 }

        
          19
        
        
          public
        
        
          double
        
         mass() { 

        
          20
        
        
          return
        
         mass;

        
          21
        
                 }

        
          22
        
        
          public
        
        
          double
        
         radius() {

        
          23
        
        
          return
        
         radius;

        
          24
        
                 }

        
          25
        
        
          public
        
        
          double
        
         surfaceGravity() {

        
          26
        
        
          return
        
         surfaceGravity;

        
          27
        
                 }

        
          28
        
        
          public
        
        
          double
        
         surfaceWeight(
        
          double
        
         mass) {

        
          29
        
        
          return
        
         mass * surfaceGravity;

        
          30
        
                 }

        
          31
        
             }
      

? ? ? 在上面的枚舉示例代碼中,已經將數據和枚舉常量關聯起來了,因此需要聲明實例域字段,同時編寫一個帶有數據并將數據保存在域中的構造器。枚舉天生就是不可變的,因此所有的域字段都應該為final的。下面看一下該枚舉的應用示例:

        
           1
        
        
          public
        
        
          class
        
         WeightTable {

        
           2
        
        
          public
        
        
          static
        
        
          void
        
         main(String[] args) {

        
           3
        
        
          double
        
         earthWeight = Double.parseDouble(args[0]);

        
           4
        
        
          double
        
         mass = earthWeight/Planet.EARTH.surfaceGravity();

        
           5
        
        
          for
        
         (Planet p : Planet.values())

        
           6
        
                         System.out.printf("Weight on %s is %f%n",p,p.surfaceWeight(mass));

        
           7
        
                 }

        
           8
        
             }

        
           9
        
        
          //
        
        
           Weight on MERCURY is 66.133672

        
        
          10
        
        
              //
        
        
           Weight on VENUS is 158.383926

        
        
          11
        
        
              //
        
        
           Weight on EARTH is 175.000000

        
        
          12
        
        
          //
        
        
           Weight on MARS is 66.430699

        
        
          13
        
        
              //
        
        
           Weight on JUPITER is 442.693902

        
        
          14
        
        
              //
        
        
           Weight on SATURN is 186.464970

        
        
          15
        
        
              //
        
        
           Weight on URANUS is 158.349709

        
        
          16
        
        
              //
        
        
           Weight on NEPTUNE is 198.846116
        
      

?? ?? 枚舉的靜態方法values()將按照聲明順序返回他的值數組。枚舉的toString方法返回每個枚舉值的聲明名稱。
? ? ? 在實際的編程中,我們常常需要針對不同的枚舉常量提供不同的數據操作行為,見如下代碼:

        
           1
        
        
          public
        
        
          enum
        
         Operation {

        
           2
        
                 PLUS,MINUS,TIMES,DIVIDE;

        
           3
        
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) {

        
           4
        
        
          switch
        
         (
        
          this
        
        ) {

        
           5
        
        
          case
        
         PLUS: 
        
          return
        
         x + y;

        
           6
        
        
          case
        
         MINUS: 
        
          return
        
         x - y;

        
           7
        
        
          case
        
         TIMES: 
        
          return
        
         x * y;

        
           8
        
        
          case
        
         DIVIDE: 
        
          return
        
         x / y;

        
           9
        
                     }

        
          10
        
        
          throw
        
        
          new
        
         AssertionError("Unknown op: " + 
        
          this
        
        );

        
          11
        
                 }

        
          12
        
             }
      

?? ?? 上面的代碼已經表達出這種根據不同的枚舉值,執行不同的操作。但是上面的代碼在設計方面確實存在一定的缺陷,或者說漏洞,如果我們新增枚舉值的時候,所有和apply類似的域函數,都需要進行相應的修改,如有遺漏將會導致異常的拋出。幸運的是,Java的枚舉提供了一種更好的方法可以將不同的行為與每個枚舉常量關聯起來:在枚舉類型中聲明一個抽象的apply方法,并在特定于常量的類主體中,用具體的方法覆蓋每個常量的抽象apply方法,如:

        
          1
        
        
          public
        
        
          enum
        
         Operation {

        
          2
        
                 PLUS { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x + y;} },

        
          3
        
                 MINUS { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x - y;} },

        
          4
        
                 TIMES { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x * y;} },

        
          5
        
                 DIVIDE { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x / y;} };

        
          6
        
        
          abstract
        
        
          double
        
         apply(
        
          double
        
         x, 
        
          double
        
         y);

        
          7
        
             }
      

? ? ? 這樣在添加新枚舉常量時就不會輕易忘記提供相應的apply方法了。我們在進一步看一下如何將枚舉常量和特定的數據進行關聯,見如下代碼:

        
           1
        
        
          public
        
        
          enum
        
         Operation {

        
           2
        
                 PLUS("+") { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x + y;} },

        
           3
        
                 MINUS("-") { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x - y;} },

        
           4
        
                 TIMES("*") { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x * y;} },

        
           5
        
                 DIVIDE("/") { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x / y;} };

        
           6
        
        
          private
        
        
          final
        
         String symbol;

        
           7
        
                 Operation(String symbol) {

        
           8
        
        
          this
        
        .symbol = symbol;

        
           9
        
                 }

        
          10
        
                 @Override 
        
          public
        
         String toString() {

        
          11
        
        
          return
        
         symbol;

        
          12
        
                 }

        
          13
        
        
          abstract
        
        
          double
        
         apply(
        
          double
        
         x, 
        
          double
        
         y);

        
          14
        
             }
      

? ? ? 下面給出以上代碼的應用示例:

        
           1
        
        
          public
        
        
          static
        
        
          void
        
         main(String[] args) {

        
           2
        
        
          double
        
         x = Double.parseDouble(args[0]);

        
           3
        
        
          double
        
         y = Double.parseDouble(args[1]);

        
           4
        
        
          for
        
         (Operation op : Operation.values())

        
           5
        
                     System.out.printf("%f %s %f = %f%n",x,op,y,op.apply(x,y));

        
           6
        
                 }

        
           7
        
             }

        
           8
        
        
          //
        
        
           2.000000 + 4.000000 = 6.000000

        
        
           9
        
        
              //
        
        
           2.000000 - 4.000000 = -2.000000

        
        
          10
        
        
              //
        
        
           2.000000 * 4.000000 = 8.000000

        
        
          11
        
        
          //
        
        
           2.000000 / 4.000000 = 0.500000
        
      

?? ?? 沒有類型有一個自動產生的valueOf(String)方法,他將常量的名字轉變為枚舉常量本身,如果在枚舉中覆蓋了toString方法(如上例),就需要考慮編寫一個fromString方法,將定制的字符串表示法變回相應的枚舉,見如下代碼:

        
           1
        
        
          public
        
        
          enum
        
         Operation {

        
           2
        
                 PLUS("+") { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x + y;} },

        
           3
        
                 MINUS("-") { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x - y;} },

        
           4
        
                 TIMES("*") { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x * y;} },

        
           5
        
                 DIVIDE("/") { 
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x / y;} };

        
           6
        
        
          private
        
        
          final
        
         String symbol;

        
           7
        
                 Operation(String symbol) {

        
           8
        
        
          this
        
        .symbol = symbol;

        
           9
        
                 }

        
          10
        
                 @Override 
        
          public
        
         String toString() {

        
          11
        
        
          return
        
         symbol;

        
          12
        
                 }

        
          13
        
        
          abstract
        
        
          double
        
         apply(
        
          double
        
         x, 
        
          double
        
         y);

        
          14
        
        
          //
        
        
          新增代碼
        
        
        
        
          15
        
        
          private
        
        
          static
        
        
          final
        
         Map<String,Operation> stringToEnum = 
        
          new
        
         HashMap<String,Operation>();

        
          16
        
        
          static
        
         {

        
          17
        
        
          for
        
         (Operation op : values())

        
          18
        
                         stringToEnum.put(op.toString(),op);

        
          19
        
                 }

        
          20
        
        
          public
        
        
          static
        
         Operation fromString(String symbol) {

        
          21
        
        
          return
        
         stringToEnum.get(symbol);

        
          22
        
                 }

        
          23
        
             }
      

? ? ? 需要注意的是,我們無法在枚舉常量構造的時候將自身放入到Map中,這樣會導致編譯錯誤。與此同時,枚舉構造器不可以訪問枚舉的靜態域,除了編譯時的常量域之外。
?? ?
三十一、用實例域代替序數:

?? ?? Java中的枚舉提供了ordinal()方法,他返回每個枚舉常量在類型中的數字位置,如:

        
          1
        
        
          public
        
        
          enum
        
         Color {

        
          2
        
                 WHITE,RED,GREEN,BLUE,ORANGE,BLACK;

        
          3
        
        
          public
        
        
          int
        
         indexOfColor() {

        
          4
        
        
          return
        
         ordinal() + 1;

        
          5
        
                 }

        
          6
        
             }
      

? ? ? 上面的枚舉中提供了一個獲取顏色索引的方法(indexOfColor),該方法將返回顏色值在枚舉類型中的聲明位置,如果我們的外部程序依賴了該順序值,那么這將會是非常危險和脆弱的,因為一旦這些枚舉值的位置出現變化,或者在已有枚舉值的中間加入新的枚舉值時,都將導致該索引值的變化。該條目推薦使用實例域的方式來代替枚舉提供的序數值,見如下修改后的代碼:

        
           1
        
        
          public
        
        
          enum
        
         Color {

        
           2
        
                 WHITE(1),RED(2),GREEN(3),ORANGE(4),BLACK(5);

        
           3
        
        
          private
        
        
          final
        
        
          int
        
         indexOfColor;

        
           4
        
                 Color(
        
          int
        
         index) {

        
           5
        
        
          this
        
        .indexOfColor = index;

        
           6
        
                 }

        
           7
        
        
          public
        
        
          int
        
         indexOfColor() {

        
           8
        
        
          return
        
         indexOfColor;

        
           9
        
                 }

        
          10
        
             }
      

? ? ? Enum規范中談到ordinal時這么寫道:“大多數程序員都不需要這個方法。它是設計成用于像EnumSet和EnumMap這種基于枚舉的通用數據結構的。”除非你在編寫的是這種數據結構,否則最好避免使用ordinal()方法。
?? ?
三十二、用EnumSet代替位域:

? ? ? 下面的代碼給出了位域的實現方式:

        
          1
        
        
          public
        
        
          class
        
         Text {

        
          2
        
        
          public
        
        
          static
        
        
          final
        
        
          int
        
         STYLE_BOLD = 1 << 0;

        
          3
        
        
          public
        
        
          static
        
        
          final
        
        
          int
        
         STYLE_ITALIC = 1 << 1;

        
          4
        
        
          public
        
        
          static
        
        
          final
        
        
          int
        
         STYLE_UNDERLINE = 1 << 2;

        
          5
        
        
          public
        
        
          static
        
        
          final
        
        
          int
        
         STYLE_STRIKETHROUGH = 1 << 3;

        
          6
        
        
          public
        
        
          void
        
         applyStyles(
        
          int
        
         styles) { ... }

        
          7
        
             }
      

? ? ? 這種表示法讓你用OR位運算將幾個常量合并到一個集合中,使用方式如下:
? ? ? text.applyStyles(Text.STYLE_BOLD | Text.STYLE_ITALIC);
? ? ? Java中提供了EnumSet類,該類繼承自Set接口,同時也提供了豐富的功能,類型安全性,以及可以從任何其他Set實現中得到的互用性。但是在內部具體實現上,沒有EnumSet內容都表示為位矢量。如果底層的枚舉類型有64個或者更少的元素,整個EnumSet就用單個long來表示,因此他的性能也是可以比肩位域的。與此同時,他提供了大量的操作方法,其實現也是基于位操作的,但是相比于手工位操作,由于EnumSet替我們承擔了這部分的開發,從而也避免了一些容易出現的低級錯誤,代碼的美觀程度也會有所提升,見如下修改的代碼:

        
          1
        
        
          public
        
        
          class
        
         Text {

        
          2
        
        
          public
        
        
          enum
        
         Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH }

        
          3
        
        
          public
        
        
          void
        
         applyStyles(Set<Style> styles) { ... }

        
          4
        
             }
      

? ? ? 新的使用方式如下:
? ? ? text.applyStyles(EnumSet.of(Style.BOLD,Style.ITALIC));
? ? ? 需要說明的是,EnumSet提供了豐富的靜態工廠來輕松創建集合。

?

三十三、用EnumMap代替序數索引:

?? ?? 前面的條目已經給出了盡量不要直接使用枚舉的ordinal()方法的原因,這里就不在做過多的贅述了。在這個條目中,只是再一次給出了ordinal()的典型用法,與此同時也再一次提供了一個更為合理的解決方案用于替換ordinal()方法,從而進一步證明我們在編碼過程中應該盡可能減少對枚舉中ordinal()函數的依賴。見如下代碼:

        
           1
        
        
          public
        
        
          class
        
         Herb {

        
           2
        
        
          public
        
        
          enum
        
         Type { ANNUAL, PERENNIAL, BIENNIAL }

        
           3
        
        
          private
        
        
          final
        
         String name;

        
           4
        
        
          private
        
        
          final
        
         Type type;

        
           5
        
                 Herb(String name, Type type) {

        
           6
        
        
          this
        
        .name = name;

        
           7
        
        
          this
        
        .type = type;

        
           8
        
                 }

        
           9
        
                 @Override 
        
          public
        
         String toString() {

        
          10
        
        
          return
        
         name;

        
          11
        
                 }

        
          12
        
             }

        
          13
        
        
          public
        
        
          static
        
        
          void
        
         main(String[] args) {

        
          14
        
                 Herb[] garden = getAllHerbsFromGarden();

        
          15
        
                 Set<Herb> herbsByType = (Set<Herb>[])
        
          new
        
         Set[Herb.Type.values().length];

        
          16
        
        
          for
        
         (
        
          int
        
         i = 0; i < herbsByType.length; ++i) {

        
          17
        
                     herbsByType[i] = 
        
          new
        
         HashSet<Herb>();

        
          18
        
                 }

        
          19
        
        
          for
        
         (Herb h : garden) {

        
          20
        
                     herbsByType[h.type.ordinal()].add(h);

        
          21
        
                 }

        
          22
        
        
          for
        
         (
        
          int
        
         i = 0; i < herbsByType.length; ++i) {

        
          23
        
                     System.out.printf("%s: %s%n",Herb.Type.values()[i],herbByType[i]);

        
          24
        
                 }

        
          25
        
             }
      

?? ?? 這里我需要簡單描述一下上面代碼的應用場景:在一個花園里面有很多的植物,它們被分成3類,分別是一年生(ANNUAL)、多年生(PERENNIAL)和兩年生(BIENNIAL),正好對應著Herb.Type中的枚舉值。現在我們需要做的是遍歷花園中的每一個植物,并將這些植物分為3類,最后再將分類后的植物分類打印出來。下面將提供另外一種方法,即通過EnumMap來實現和上面代碼相同的邏輯:

        
           1
        
        
          public
        
        
          static
        
        
          void
        
         main(String[] args) {

        
           2
        
                 Herb[] garden = getAllHerbsFromGarden();

        
           3
        
                 Map<Herb.Type,Set<Herb>> herbsByType = 

        
           4
        
        
          new
        
         EnumMap<Herb.Type,Set<Herb>>(Herb.Type.
        
          class
        
        );

        
           5
        
        
          for
        
         (Herb.Type t : Herb.Type.values()) {

        
           6
        
                     herbssByType.put(t,
        
          new
        
         HashSet<Herb>());

        
           7
        
                 }

        
           8
        
        
          for
        
         (Herb h : garden) {

        
           9
        
                     herbsByType.get(h.type).add(h);

        
          10
        
                 }

        
          11
        
                 System.out.println(herbsByType);

        
          12
        
             }
      

?? ?? 和之前的代碼相比,這段代碼更加清晰,也更加安全,運行效率方面也是可以與使用ordinal()的方式想媲美的。

三十四、用接口模擬可伸縮的枚舉:

?? ?? 枚舉是無法被擴展(extends)的,這是一個無法回避的事實。如果我們的操作中存在一些基礎操作,如計算器中的基本運算類型(加減乘除)。然而對于有些用戶來講,他們也可以使用更高級的操作,如求冪和求余等。針對這樣的需求,該條目提出了一種非常巧妙的設計方案,即利用枚舉可以實現接口這一事實,我們將API的參數定義為該接口,而不是具體的枚舉類型,見如下代碼:

        
           1
        
        
          public
        
        
          interface
        
         Operation {

        
           2
        
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y);

        
           3
        
             }

        
           4
        
        
          public
        
        
          enum
        
         BasicOperation 
        
          implements
        
         Operation {

        
           5
        
                 PLUS("+") {

        
           6
        
        
          public
        
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x + y; }

        
           7
        
                 },

        
           8
        
                 MINUS("-") {

        
           9
        
        
          public
        
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x - y; }

        
          10
        
                 },

        
          11
        
                 TIMES("*") {

        
          12
        
        
          public
        
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x * y; }

        
          13
        
                 },

        
          14
        
                 DIVIDE("/") {

        
          15
        
        
          public
        
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) { 
        
          return
        
         x / y; }

        
          16
        
                 };

        
          17
        
        
          private
        
        
          final
        
         String symbol;

        
          18
        
                 BasicOperation(String symbol) {

        
          19
        
        
          this
        
        .symbol = symbol;

        
          20
        
                 }

        
          21
        
                 @Override 
        
          public
        
         String toString() {

        
          22
        
        
          return
        
         symbol;

        
          23
        
                 }

        
          24
        
             }

        
          25
        
        
          public
        
        
          enum
        
         ExtendedOperation 
        
          implements
        
         Operation {

        
          26
        
                 EXP("^") {

        
          27
        
        
          public
        
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) {

        
          28
        
        
          return
        
         Math.pow(x,y);

        
          29
        
                     }

        
          30
        
                 },

        
          31
        
                 REMAINDER("%") {

        
          32
        
        
          public
        
        
          double
        
         apply(
        
          double
        
         x,
        
          double
        
         y) {

        
          33
        
        
          return
        
         x % y;

        
          34
        
                     }

        
          35
        
                 };

        
          36
        
        
          private
        
        
          final
        
         String symbol;

        
          37
        
                 ExtendedOperation(String symbol) {

        
          38
        
        
          this
        
        .symbol = symbol;

        
          39
        
                 }

        
          40
        
                 @Override 
        
          public
        
         String toString() {

        
          41
        
        
          return
        
         symbol;

        
          42
        
                 }

        
          43
        
             }
      

????? 通過以上的代碼可以看出,在任何可以使用BasicOperation的地方,我們也同樣可以使用ExtendedOperation,只要我們的API是基于Operation接口的,而非BasicOperation或ExtendedOperation。下面為以上代碼的應用示例:

        
           1
        
        
          public
        
        
          static
        
        
          void
        
         main(String[] args) {

        
           2
        
        
          double
        
         x = Double.parseDouble(args[0]);

        
           3
        
        
          double
        
         y = Double.parseDouble(args[1]);

        
           4
        
                 test(ExtendedOperation.
        
          class
        
        ,x,y);

        
           5
        
             }

        
           6
        
        
          private
        
        
          static
        
         <T 
        
          extends
        
         Enum<T> & Operation> 
        
          void
        
         test(

        
           7
        
                 Class<T> opSet,
        
          double
        
         x,
        
          double
        
         y) {

        
           8
        
        
          for
        
         (Operation op : opSet.getEnumConstants()) {

        
           9
        
                     System.out.printf("%f %s %f = %f%n",x,op,y,op.apply(x,y));

        
          10
        
                 }

        
          11
        
             }
      

????? 注意,參數Class<T> opSet將推演出類型參數的實際類型,即上例中的ExtendedOperation。與此同時,test函數的參數類型限定確保了類型參數既是枚舉類型又是Operation的實現類,這正是遍歷元素和執行每個元素相關聯的操作所必須的。

?

Effective Java (枚舉)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久国产欧美日韩精品免费 | 欧美日韩一级黄色片 | 日本一级特大毛片 | 777奇米影视久久激情日韩欧美 | 元龙第三季免费观看 | 欧美亚洲国产日韩一区二区三区 | 日日插夜夜操 | 国产区精品 | jizzjizz中国护士第一次 | 香蕉黄视频 | 天天干天天舔天天操 | 国产高清在线精品一区二区 | 亚洲国内 | 国产视频二区在线观看 | www.国产| 久久女同互慰一区二区三区 | 久久99爱视频 | 91麻豆精品国产91久久久久 | 亚洲香蕉在线观看 | 亚洲视频免费在线播放 | 国产精品资源在线观看 | 日韩精品中文字幕一区三区 | 欧美成人一区二区三区在线电影 | 婷婷四房 | 久久久久久网 | 欧美日韩网站 | 久久久久久99 | 亚洲精品久久久久久久久久久网站 | 老司机深夜福利影院 | 99香蕉国产精品偷在线观看 | 国产一区二区三区不卡观 | 五月色婷婷综合激情免费视频 | 国产精品露脸张开双腿 | 中文字幕一二三区乱码老 | 久久视频在线免费观看 | 国产午夜影院 | 国产中文字幕在线免费观看 | 国产色婷婷精品综合在线手机播放 | 四虎在线免费观看视频 | 在线亚洲欧美 | 久久国产精品亚洲综合 |