枚举Enum与注解Aunotation大杂烩
文章目錄
- 一、枚舉類
- 1. 為什么使用枚舉類?
- 2. 枚舉類的實現和屬性概述
- 3. 自定義枚舉類
- 4. 使用enum的定義枚舉類
- 5. 常用的Enum方法
- 6. 枚舉類實現接口
- 二、注解(Annotation)
- 1. 注解概述
- 2. 常見的注解示例
- 3. 如何自定義注解
- 4. JDK 中的元注解
- 5. 利用反射獲取注解信息
- 6. JDK8 中注解的新特性
本篇文章已同步到:https://www.bithachi.cn/posts/3aa86aea.html
一、枚舉類
1. 為什么使用枚舉類?
枚舉在曰常生活中很常見,舉例如下:
當需要定義一組常量時,我們把常量抽象成類對象去處理,使用枚舉定義常量更安全,更便捷,更直觀。
2. 枚舉類的實現和屬性概述
若枚舉只有一個對象, 則可以作為一種單例模式的實現方式。
枚舉類的實現:
- JDK1.5之前需要自定義枚舉類
- JDK 1.5 新增的 enum 關鍵字用于定義枚舉類
枚舉類的屬性:
- 枚舉類對象的屬性不應允許被改動, 所以應該使用 private final修飾
- 枚舉類使用 private final 修飾的屬性應該在構造器中為其賦值
- 若枚舉類顯式的定義了帶參數的構造器, 則在列出枚舉值時也必須對應的 傳入參數
3. 自定義枚舉類
運行結果:
Season{seasonName='春天', seasonDesc='春暖花開'}4. 使用enum的定義枚舉類
使用說明:
- 使用 enum 定義的枚舉類默認繼承了java.lang.Enum類,因此不能再繼承其他類
- 枚舉類的構造器只能使用 private 權限修飾符
- 枚舉類的所有實例必須在枚舉類中顯式列出(, 分隔 ; 結尾)。列出的實例系統會自動添加 public static final修飾
- 必須在枚舉類的第一行聲明枚舉類對象
- JDK 1.5 中可以在 switch 表達式中使用Enum定義的枚舉類的對象作為表達式, case 子句可以直接使用枚舉值的名字, 無需添加枚舉
類作為限定。
運行結果:
SUMMER 夏天 夏日炎炎5. 常用的Enum方法
Enum類的主要方法:
- values() 方法:返回枚舉類型的對象數組。該方法可以很方便地遍歷所有的枚舉值。
- valueOf(String str):返回指定字符串對應的枚舉類對象。要求字符串必須是枚舉類對象的“名字”。如不是,會有運行時異常:
IllegalArgumentException。 - toString():返回當前枚舉類對象常量的名稱
運行結果:
SPRING,春天,春暖花開 SUMMER,夏天,夏日炎炎 AUTUMN,秋天,秋高氣爽 WINTER,冬天,冰天雪地 **************** NEW RUNNABLE BLOCKED WAITING TIMED_WAITING TERMINATED **************** SUMMER,夏天,夏日炎炎其它方法:
6. 枚舉類實現接口
- 和普通 Java 類一樣,枚舉類可以實現一個或多個接口
- 若每個枚舉值在調用實現的接口方法呈現相同的行為方式,則只要統一實現該方法即可。
- 若需要每個枚舉值在調用實現的接口方法呈現出不同的行為方式,則可以讓每個枚舉值分別來實現該方法
運行結果:
SPRING,春天,春暖花開,春天在哪里? SUMMER,夏天,夏日炎炎,夏天好熱! AUTUMN,秋天,秋高氣爽,秋天不回來 WINTER,冬天,冰天雪地,大約在冬季二、注解(Annotation)
1. 注解概述
- 從 JDK 5.0 開始, Java 增加了對元數據(MetaData) 的支持, 也就是Annotation(注解)
- Annotation 其實就是代碼里的 特殊標記, 這些標記可以在編譯, 類加載, 運行時被讀取, 并執行相應的處理。
- 通過使用Annotation, 程序員可以在不改變原有邏輯的情況下, 在源文件中嵌入一些補充信息。代碼分析工具、開發工具和部署工具可以通過這些補充信息進行驗證或者進行部署。
- Annotation 可以像修飾符一樣被使用, 可用于修飾包, 類, 構造器, 法, 成員變量, 參數, 局部變量的聲明,這些信息被保存在 Annotation的 “name=value”對中。
- 在JavaSE中,注解的使用目的比較簡單,例如標記過時的功能,忽略警告等。
- 在JavaEE/Android中注解占據了更重要的角色,例如用來配置應用程序的任何切面,代替JavaEE舊版中所遺留的繁冗代碼和XML配置等。
- 未來的開發模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,現在的
Struts2有一部分也是基于注解的了,注解是一種趨勢,一定程度上可以說:框架 = 注解 + 反射 + 設計模式。 - 使用 Annotation 時要在其前面增加@符號, 并 把該 Annotation 當成一個修飾符使用。用于修飾它支持的程序元素。
2. 常見的注解示例
示例一:生成文檔相關的注解
@author 標明開發該類模塊的作者,多個作者之間使用,分割
@version標明該類模塊的版本
@see 參考轉向,也就是相關主題
@since 從哪個版本開始增加的
@param對方法中某參數的說明,如果沒有參數就不能寫
@return 對方法返回值的說明,如果方法的返回值類型是void就不能寫
@exception 對方法可能拋出的異常進行說明 ,如果方法沒有用throws顯式拋出的異常就不能寫
其中:
- @param @return 和 @exception 這三個標記都是只用于方法的。
- @param的格式要求:@param 形參名 形參類型 形參說明
- @return 的格式要求:@return 返回值類型 返回值說明
- @exception的格式要求:@exception 異常類型 異常說明
- @param和@exception可以并列多個
示例二: 在編譯時進行格式檢查(JDK 內置的三個基本注解)
- @Override: 限定重寫父類方法, 該注解只能用于方法
- @Deprecated:用于表示所修飾的元素(類, 方法等)已過時。通常是因為所修飾的結構危險或存在更好的選擇
- @SuppressWarnings: 抑制編譯器警告;(如果一些類,屬性,方法沒有使用,則編譯器會警告,友情提示警告你寫的代碼浪費空間資源)
示例三: 跟蹤 代碼依賴性,實現替代配置文件功能
- Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中進行Servlet的部署。
- spring框架中關于“事務”的管理
3. 如何自定義注解
- 定義新的 Annotation 類型使用@interface關鍵字
- 自定義注解自動繼承了java.lang.annotation.Annotation 接口
- Annotation 的成員變量在 Annotation 定義中以無參數方法的形式來聲明。其方法名和返回值定義了該成員的名字和類型。我們稱為配置參數。類型只能是八種基本數據類型、String 類型 、Class 類型 、enum 類型 、Annotation 類型 、以上所有類型的 數組。
- 可以在定義 Annotation 的成員變量時為其指定初始值, 指定成員變量的初始值可使用default關鍵字
- 如果只有一個參數成員,建議使用 參數名為value
- 如果定義的注解含有配置參數,那么使用時必須指定參數值,除非它有默認值。格式是“參數名 = 參數值”,如果只有一個參數成員,且名稱為value,可以省略“value=”
- 沒有成員定義的 Annotation 稱為標記; 包含成員變量的 Annotation 稱為元數據 Annotation
- 注意:自定義注解必須配上注解的信息處理流程才有意義。
使用自定義注解:
@MyAnnotation(value="hi")//注解沒有default,就需要在使用時初始化值 class Person{private String name;private int age;public Person() {}@MyAnnotationpublic Person(String name, int age) {this.name = name;this.age = age;}@MyAnnotationpublic void walk(){System.out.println("人走路");}public void eat(){System.out.println("人吃飯");} }4. JDK 中的元注解
-
JDK 的元 Annotation 用于修飾其他 Annotation 定義,對現有注解進行解釋說明的注解叫元注解
-
JDK5.0提供了4個標準的meta-annotation類型,分別是:
- Retention
- Target
- Documente
- Inherited
元數據:對現有數據進行解釋說明的數據叫元數據,比如String name=“BitHachi”; "BitHachi"是現有數據,String name是元數據。
@Retention
@Retention: 只能用于修飾一個 Annotation 定義, 用于指定該 Annotation 的生命周期, @Rentention 包含一個 RetentionPolicy 類型的成員變量, 使用@Rentention 時必須為該 value 成員變量指定值:
- RetentionPolicy.SOURCE:在源文件中有效(即源文件保留),編譯器直接丟棄這種策略的注釋
- RetentionPolicy.CLASS:在class文件中有效(即class保留) , 當運行 Java 程序時, JVM不會保留注解。 這是默認值
- RetentionPolicy.RUNTIME:在運行時有效(即運行時保留),當運行 Java 程序時, JVM 會保留注釋。程序 可以通過反射獲取
@Target
- @Target: 用于修飾 Annotation 定義, 用于指定被修飾的 Annotation 能用于修飾哪些程序元素。
- @Target 也包含一個名為 value 的成員變量,這個成員變量是ElementType數組。
@Documented
- @Documented: 用于指定被該元 Annotation 修飾的 Annotation 類將被javadoc 工具提取成文檔。默認情況下,javadoc是不包括注解的。
- 定義為Documented的注解必須設置Retention值為RUNTIME。
@Inherited
- @Inherited: 被它修飾的 Annotation 將具有繼承性。如果某個類使用了被@Inherited 修飾的 Annotation, 則其子類將自動具有該注解。
- 比如:如果把標有@Inherited注解的自定義的注解標注在類級別上,子類則可以繼承父類類級別的注解
- 實際應用中,使用較少
接下來介紹利用反射獲取注解信息,然后舉一個例子將以上4個元注解一起演示一遍
5. 利用反射獲取注解信息
- JDK 5.0 在 java.lang.reflect 包下新增了 AnnotatedElement 接口, 該接口代表程序中可以接受注解的程序元素
- 當一個 Annotation 類型被定義為運行時 Annotation 后, 該注解才是運行時可見, 當 class 文件被載入時保存在 class 文件中的 Annotation 才會被虛擬機讀取
- 程序可以調用 AnnotatedElement對象的如下方法來訪問 Annotation 信息
元注解與反射獲取注解信息示例:
import java.lang.annotation.*;import static java.lang.annotation.ElementType.*; //指定被該元 Annotation 修飾的 Annotation 類將被javadoc 工具提取成文檔 @Documented //子類可以繼承父類類級別的Annotation @Inherited //指定該 Annotation 的生命周期 @Retention(RetentionPolicy.RUNTIME) //指定被修飾的 Annotation 能用于修飾哪些程序元素 @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER,TYPE_USE}) public @interface MyAnnotation {String value() default "hello"; } public class AnnotationTest {public static void main(String[] args) {Class clazz = Student.class;Annotation[] annotations = clazz.getAnnotations();//獲取Student的注解信息數組for(int i = 0;i < annotations.length;i++){System.out.println(annotations[i]);}}}@MyAnnotation() class Person{private String name;private int age;public Person() {}@MyAnnotationpublic Person(String name, int age) {this.name = name;this.age = age;}@MyAnnotationpublic void walk(){System.out.println("人走路");}public void eat(){System.out.println("人吃飯");} }class Student extends Person {@Overridepublic void walk() {System.out.println("學生走路");}} @Random_name.sgm.my_Annotation.MyAnnotation(value=hello)6. JDK8 中注解的新特性
Java 8對注解處理提供了兩點改進:可重復的注解及可用于類型的注解。此外,反射也得到了加強,在Java8中能夠得到方法參數的名稱。這會簡化標注在方法參數上的注解。
可重復注解
可重復注解示例:
類型注解
- JDK1.8之后,關于元注解@Target的參數類型ElementType枚舉值多了兩個:
TYPE_PARAMETER,TYPE_USE。 - 在Java 8之前,注解只能是在聲明的地方所使用,Java8開始,注解可以應用在任何地方。
- ElementType.TYPE_PARAMETER 表示該注解能寫在類型變量的聲明語句中(如:泛型聲明)。
- ElementType.TYPE_USE 表示該注解能寫在使用類型的任何語句中
舉個例子:
//指定被該元 Annotation 修飾的 Annotation 類將被javadoc 工具提取成文檔 @Documented //子類可以繼承父類類級別的Annotation @Inherited //指定該 Annotation 的生命周期 @Retention(RetentionPolicy.RUNTIME) //指定被修飾的 Annotation 能用于修飾哪些程序元素 @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE,TYPE_PARAMETER,TYPE_USE}) @Repeatable(MyAnnotations.class) public @interface MyAnnotation {String value() default "hello"; } //該注解能寫在類型變量的聲明語句中(如:泛型聲明 T ) class Generic<@MyAnnotation T>{public void show() throws @MyAnnotation RuntimeException{//該注解能寫在使用類型的任何語句中ArrayList<@MyAnnotation String> list = new ArrayList<>();//該注解能寫在使用類型的任何語句中int num = (@MyAnnotation int) 10L;} }總結
以上是生活随笔為你收集整理的枚举Enum与注解Aunotation大杂烩的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一篇搞定异常: Exception
- 下一篇: 一名即将大三的小伙子在疫情期间的思考与总