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

歡迎訪問 生活随笔!

生活随笔

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

java

Java注解参数类型枚举值_EffectiveJava-5-枚举和注解

發布時間:2023/12/2 java 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java注解参数类型枚举值_EffectiveJava-5-枚举和注解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

用enum代替int常量

1. int枚舉:

引入枚舉前,一般是聲明一組具名的int常量,每個常量代表一個類型成員,這種方法叫做int枚舉模式。

int枚舉模式是類型不安全的,例如下面兩組常量:性別和動物種類,二者不存在任何關系,然而卻可以將ANIMAL_DOG傳入一個需要性別參數的方法中,編譯器不會出現警告,而且方法內部邏輯還會繼續執行比較等操作。

采用int枚舉模式的程序是十分脆弱的,因為int枚舉是編譯時常量,被編譯到使用它們的客戶端中,如果與枚舉常量關聯的int值發生變化客戶端就必須重新編譯,然而不重新編譯卻不會報錯,但是會導致程序的結果不準確,例如上面的常量SEX_MAN被客戶端使用,于是將其值1編譯到客戶端的.class中,然后如果API類中將SEX_MAN的值改為2,卻不重新編譯客戶端,那么客戶端得到的結果就是不準確的了。

int枚舉常量很難被翻譯成可打印的字符串,不利于開發調試。

開發過程中還可能遇到這種模式的變體,如String枚舉模式,同樣是存在上述問題。

2. 枚舉類型:

由一組固定的常量組成的合法值的類型,例如:

實現思路:通過公有靜態的final域為每個枚舉常量導出實例的類。

枚舉類型是類型安全的枚舉模式,而且完善類int枚舉模式的不足。

枚舉類型還允許添加任意的方法和域,并實現任意的接口,它提供類所以Object方法的高級實現,實現了Comparable和Serializable接口,并針對枚舉類型的可任意改變性設計了序列化方式。

特定于常量的方法實現:

在枚舉類型中聲明一個抽象方法,并在特定于常量的類主體中,用具體的方法覆蓋每個常量的抽象方法。例如下面這樣定義一個代表加減乘除等運算符的枚舉。

策略枚舉:多個枚舉常量同時共享相同的行為時,考慮使用策略枚舉。

例如下面這樣:

用實例域代替序數

序數:枚舉天生就與一個單獨的int值相關聯,所有枚舉都有一個ordinal()方法,返回每個枚舉常量在類型中的數字位置(類似于數組索引)。

永遠不要根據枚舉的序數導出與他相關聯的值,而是將它保存在一個實例域中 (Enum規范中關于ordinal()寫到:"大多數程序員都不需要這個方法,它是設計成用于像EnumSet,EnumMap這種基于枚舉的通用數據結構的)。

用EnumSet代替位域

位域:可以用or(|)位運算將幾個常量合并到一個集合中,例如下面代碼這樣:

位域的不足:具有int枚舉的所有缺點

替代方案--EnumSet:從單個枚舉類型中提取多個值,每個EnumSet內容都表示為位矢量, 如果底層的枚舉類型有64或更少的元素(大多如此),整個EnumSet就是用單個long來表示, 因此,它的性能比得上位域的性能

用EnumMap代替序數索引

使用序數索引ordinal的場景:

上面代碼實現了對花園中對植物進行分類,然而存在許多問題:

1.數組不能與泛型兼容,需要進行未受檢對轉換;

2.set數組并不知道每個索引set的set代表什么;

3. 之前有提到不推薦使用ordinal;

解決方案:EnumMap

用接口模擬可伸縮的枚舉:

雖然無法編寫可擴展的枚舉類型,卻可以通過編寫接口以及實現該接口的基礎枚舉類型,對它進行模擬,這樣允許客戶端編寫自己的枚舉來實現接口;如果API是根據接口編寫的,那么在使用基礎枚舉類型的任何地方,也都可以使用這些枚舉。例如下面代碼,還是用之前的算數運算符舉例:(但是這樣還是有些不足,就是無法實現從一個枚舉類型繼承到另一個枚舉類型,代碼少的當然可以直接復制粘貼, 如果功能比較多則可以將他們封裝在一個輔助類或靜態輔助方法中,避免代碼的復制工作)。

注解優先于命名模式

- 命名模式:有些程序元素需要通過某種工具或框架進行特殊處理

例1:JUnit測試框架原本要求用戶一定要用test作為測試方法名的開頭

例2:iOS中的init方法要求必須是initXXX()

- 命名模式缺陷:

1. 文字拼寫錯誤會導致失敗,且沒有任何提示,造成錯誤的安全感,如JUnit的測試方法testXX寫成textXX或tsetXX等

2. 無法確保他們只用于相應的程序元素,如JUnit的命名只對方法生效,將某個類命名testXX是無效的,不會報錯,但不會執行測試

3. 沒有提供將參數值與程序元素關聯起來的好方法,如JUnit想增加一種測試類別,只在拋出某種特定異常時才會成功, 而這個異常類型需要用戶通過參數進行自定義,這種實現通過命名模式實現(將異常類型編寫到方法名中)并不理想。

注解對上面問題的解決,請看下面代碼:

堅持使用Override注解

應該在想要覆蓋超類聲明的每個方法聲明中使用Override注解 例如我們經常會重寫自定義模型類的equals方法,下面用代碼說明使用Override注解的優勢。

使用Override還有一點好處,就是可以區分哪些方法是超類對,哪些方法子類擴展對

用標記接口定義類型

標記接口:沒有方法聲明,只是表示具有某種屬性,如Serializable接口

標記接口的優點 :

1. 標記接口定義的類型是由被標記類的實例實現的,標記注解則沒有這樣的類型

2. 標記接口可以更加精確的被鎖定,可以是對其他接口的擴展,也可以被其他標記接口擴展,如Collection和Set

標記注解的優點:1. 可以通過默認方式添加一個或多個注解類型的元素,給已被使用的注解類型添加更多的信息,方便擴展

2. 另一個優點在于它們是更大的注解機制的一部分,因此,標記注解,在那些支持注解作為編程元素之一的框架中同樣具有一致性

如何選擇?

- 如果標記是應用到任何程序元素而不只是類或接口,那就必須使用注解

- 如果只是用于類或接口,需要考慮要編寫只接受有這種標記的方法,使用接口作為相關方法的參數類型, 可以提供編譯時就進行類型檢查的好處

- 是否要永遠限制這個標記只用于特殊接口的元素,如果是,最好將標記定義成該接口的一個子接口

我是今陽,如果想要進階和了解更多的干貨,歡迎關注公眾號”今陽說“接收我的最新文章

總結

以上是生活随笔為你收集整理的Java注解参数类型枚举值_EffectiveJava-5-枚举和注解的全部內容,希望文章能夠幫你解決所遇到的問題。

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