日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Effective Java读书笔记二:枚举和注解

發布時間:2025/3/21 java 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Effective Java读书笔记二:枚举和注解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第30條:用enum代替int常量

當需要一組固定常量的時候,應該使用enum代替int常量,除了對于手機登資源有限的設備應該酌情考慮enum的性能弱勢之外。

第31條:用實例域代替序數

枚舉的ordinal()方法會返回枚舉常量在類型中的數字位置, 但是盡量不要使用它,因為當重新排序后,會對客戶端造成破壞。 正確的做法是,將他保存在一個實例域中。

應該給enum添加int域,而不是使用ordinal方法來導出與枚舉關聯的序數值。(幾乎不應使用ordinal方法,除非在編寫像EnumMap這樣的基于枚舉的通用數據結構)

//WRONG public enum Fruit{APPLE, PEAR, ORANGE;public int numberOfFruit(){return ordinal() + 1;} }//RIGHT public enum Fruit{APPLE(1), PEAR(2), ORANGE(3);private final int number;Fruit(int num) {number = num;}public int numberOfFruit(){return number;} }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

第32條:用EnumSet代替位域

每個EnumSet的內容都表示為位矢量。如若底層的枚舉類型個數小于64個,則整個EnumSet就用單個long來表示,因此性能上比的上位域。

//WRONG public class Text{private static final int STYLE_BOLD = 1 << 0;private static final int STYLE_ITALIC = 1 << 1;private static final int STYLE_UNDERLINE = 1 << 2;public void applyStyles(int styles) {...} } //use text.applyStyles(STYLE_BOLD | STYLE_ITALIC);//RIGHT public class Text{public enum Style{STYLE_BOLD, STYLE_ITALIC, STYLE_UNDERLINE}public void applyStyles(Set<Style> styles) {...} //這里不使用EnumSet<Style>參數是因為考慮到某些客戶端可能會傳遞一些其他的Set實現 } //use text.applyStyles(EnumSet.of(STYLE_BOLD, STYLE_ITALIC));
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • EnumSet 實現了 Set 接口,提供了豐富的功能,類型安全.可以從其他任何Set中得到互換性.
  • 整個 EnumSet 就是用 單個 long 來表示的,性能上比得上 位運算的性能.
  • 總而言之因為枚舉類型要用在集合(Set)中,所以沒有理由用位域來表示.
  • 第33條:用EnumMap代替序數索引

    序數索引是指依賴于枚舉成員在枚舉中的序數來進行數組索引,如:

    //定義了植物類,其中植物又分為水果,蔬菜,樹木三種 public class Plant{public enum Type { Fruit, Vegetables, Tree}private final String name;private final Type type;Plant(String name, Type type){this.name = name;this.type = type;} }Set<Plant>[] plants = (Set<Plant>[]) new Set[Plant.Type.valuse().lenght]; //根據植物的類型,分別把所有的植物放入三個set中 for(int i = 0; i < plant.lenght; i++){plant[i] = new HashSet<Plant>(); }for(Plant p : garden){ //garden里放了所有的植物plant[p.type.ordinal()].add(p) //反面教材:利用了枚舉的序數來得到想要的數組索引,用戶在其他地方可以不使用ordinal函數,而直接使用int值來訪問,就可能出錯 }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    應該使用EnumMap來實現,EnumMap內部是采用數組實現的,具有Map的豐富功能和類型安全以及數組 的效率:

    Map<Plant.Type, Set<Plant>> plants = new EnumMap<Plant.Type, Set<Plant>>(Plant.Type.class); //構造函數需要 鍵 類型的Class對象 //根據植物的類型,分別把所有的植物放入三個set中 for(Plant.Type type : Plant.Type.valuse()){plant.put(type, new HashSet<Plant>); }for(Plant p : garden){ //garden里放了所有的植物plant.get(p.type).add(p) //用戶必須使用正確的鍵值來訪問,即Type類型 }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    當需要多維關系時,可以使用EnumMap<…, EnumMap<…>>

    第34條:用接口模擬可以伸縮的枚舉

    1、如果讓一個 枚舉類型 去擴展另一個 枚舉類型,利用語言的特性,幾乎是不可能的?
    2、枚舉的可擴展性,到最后都證明不是一個好點子.

    由于在Java中enum不是可擴展的,在某些情況下,可能需要對枚舉進行擴展,比如操作類型(+-*/等),就可以考慮:?
    1.定義一個接口,比如public interface Operation{…};?
    2.使枚舉繼承接口:比如public enum BasicOperation implements Operation{…}?
    3.使用時的API寫成接口(比如,T extends Enum & Operation),而不是實現(比如BasicOperation )

    private static <T extends Enum<T> & Operation> void function(T t,..); //表示T即表示枚舉又是Operation的子類型
    • 1
    • 1

    4.當需要擴展BasicOperation枚舉時,就可以另寫一個枚舉,且implements接口Operation

    第35條:注解優先于命名模式

    優先使用注解來表面針對某些程序元素的特定信息。?
    注解的優勢:

  • @Retention : 限定保留時期
  • @Target: 限定其應用的程序元素
  • 還有很多注解,如 @IntDef,@ViewDebug…
  • 注解接收的參數如果是數組,為其賦值一個單獨的元素也是合法的
  • 第36條:堅持使用Override注解

    在想要覆蓋的方法上使用Override注解,編譯器就可以幫助發現一些錯誤。可以不寫Override的特例:在具體類中不必標注你確信覆蓋了抽象方法聲明的方法(雖然這么做也沒有什么壞處)。

    第37條:用標記接口實現類型

    標記分為標記接口和標記注解。

    標記接口:沒有包含方法聲明的接口,只是指明某個類實現了具有某種屬性的接口。比如Serializable接口,通過實現這個接口,類表明它的實例可以被寫到ObjectOutputStream。。

    標記接口與標記注解的最終要的區別在于:?
    標記接口可以在編譯時就檢查到相應的類型問題,而標記注解則要到運行時。

    標記接口優勢:

  • 標記接口定義的類型是由 被標記的類的實例 實現的,標記注解 則沒有定義這樣的類型
  • 他們可以被更加精確的進行鎖定,比如?
    如果注解類型利用 @Target(ElementType.TYPE) 標記,則它可以被應用到任何類或者接口上
  • 標記注解優勢:

  • 它可以 通過默認的方式 添加 一個或者多個注解類型元素,給 已被使用的注解類型添加更多的信息.隨著時間的推移,簡單的標記注解類型可以演變成更加豐富的注解類型.
  • 他們是更大的注解機制的一部分.
  • 使用:

  • 如果標記是應用到任何程序元素而不是類或者接口,就必須使用注解. 因為只有 類和接口可以用來實現或者擴展接口
  • 如果標記只應用給類和接口,就應該 優先使用標記接口而非注解
  • 《Effective Java中文版 第2版》PDF版下載:?
    http://download.csdn.net/detail/xunzaosiyecao/9745699

    作者:jiankunking 出處:http://blog.csdn.net/jiankunking

    from:?http://blog.csdn.net/jiankunking/article/details/54844842

    總結

    以上是生活随笔為你收集整理的Effective Java读书笔记二:枚举和注解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。