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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

枚举Enum与注解Aunotation大杂烩

發布時間:2024/10/14 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 枚举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. 為什么使用枚舉類?

枚舉在曰常生活中很常見,舉例如下:

  • 星期:Monday(星期一)、…、Sunday(星期天)
  • 性別:Man(男)、W oman(女)
  • 季節:Spring(春節)…Winter(冬天)
  • 支付方式:Cash(現金)、WeChatPay(微信)、Alipay(支付寶)、BankCard(銀行卡)、CreditCard(信用卡)
  • 就職狀態:Busy、Free、Vocation、Dimission
  • 訂單狀態:Nonpayment(未付款)、Paid(已付款)、Delivered(已發貨)、Return(退貨)、Checked(已確認)Fulfilled(已配貨)、
  • 線程狀態:創建、就緒、運行、阻塞、死亡
  • 當需要定義一組常量時,我們把常量抽象成類對象去處理,使用枚舉定義常量更安全,更便捷,更直觀。

    2. 枚舉類的實現和屬性概述

    若枚舉只有一個對象, 則可以作為一種單例模式的實現方式。

    枚舉類的實現:

    • JDK1.5之前需要自定義枚舉類
    • JDK 1.5 新增的 enum 關鍵字用于定義枚舉類

    枚舉類的屬性:

    • 枚舉類對象的屬性不應允許被改動, 所以應該使用 private final修飾
    • 枚舉類使用 private final 修飾的屬性應該在構造器中為其賦值
    • 若枚舉類顯式的定義了帶參數的構造器, 則在列出枚舉值時也必須對應的 傳入參數

    3. 自定義枚舉類

  • 私有化類的構造器,保證不能在類的外部創建其對象
  • 在類的內部創建枚舉類的實例。聲明為:public static final
  • 對象如果有實例變量,應該聲明為private final,并在構造器中初始化
  • public class SeasonTest {public static void main(String[] args) {Season spring = Season.SPRING;System.out.println(spring);}} //自定義枚舉類 class Season{//1.聲明Season對象的屬性:private final修飾private final String seasonName;private final String seasonDesc;//2.私有化類的構造器,并給對象屬性賦值private Season(String seasonName,String seasonDesc){this.seasonName = seasonName;this.seasonDesc = seasonDesc;}//3.提供當前枚舉類的多個對象:public static final的public static final Season SPRING = new Season("春天","春暖花開");public static final Season SUMMER = new Season("夏天","夏日炎炎");public static final Season AUTUMN = new Season("秋天","秋高氣爽");public static final Season WINTER = new Season("冬天","冰天雪地");//4.獲取枚舉類對象的屬性public String getSeasonName() {return seasonName;}public String getSeasonDesc() {return seasonDesc;}//4.toString()@Overridepublic String toString() {return "Season{" +"seasonName='" + seasonName + '\'' +", seasonDesc='" + seasonDesc + '\'' +'}';} }

    運行結果:

    Season{seasonName='春天', seasonDesc='春暖花開'}

    4. 使用enum的定義枚舉類

    使用說明:

    • 使用 enum 定義的枚舉類默認繼承了java.lang.Enum類,因此不能再繼承其他類
    • 枚舉類的構造器只能使用 private 權限修飾符
    • 枚舉類的所有實例必須在枚舉類中顯式列出(, 分隔 ; 結尾)。列出的實例系統會自動添加 public static final修飾
    • 必須在枚舉類的第一行聲明枚舉類對象
    • JDK 1.5 中可以在 switch 表達式中使用Enum定義的枚舉類的對象作為表達式, case 子句可以直接使用枚舉值的名字, 無需添加枚舉
      類作為限定。
    public class SeasonTest1 {public static void main(String[] args) {Season1 s1=Season1.SUMMER;System.out.println(s1);System.out.println(s1.getSeasonName());System.out.println(s1.getSeasonDesc());} }//使用enum關鍵字定義枚舉類 enum Season1{//1.提供當前枚舉類的對象,多個對象之間用","隔開,末尾對象";"結束SPRING("春天","春暖花開"),SUMMER("夏天","夏日炎炎"),AUTUMN("秋天","秋高氣爽"),WINTER("冬天","冰天雪地");//2.聲明Season對象的屬性:private final修飾private final String seasonName;private final String seasonDesc;//3.私有化類的構造器,并給對象屬性賦值private Season1(String seasonName,String seasonDesc){this.seasonName = seasonName;this.seasonDesc = seasonDesc;}//4.獲取枚舉類對象的屬性public String getSeasonName() {return seasonName;}public String getSeasonDesc() {return seasonDesc;} }

    運行結果:

    SUMMER 夏天 夏日炎炎

    5. 常用的Enum方法

    Enum類的主要方法:

    • values() 方法:返回枚舉類型的對象數組。該方法可以很方便地遍歷所有的枚舉值。
    • valueOf(String str):返回指定字符串對應的枚舉類對象。要求字符串必須是枚舉類對象的“名字”。如不是,會有運行時異常:
      IllegalArgumentException。
    • toString():返回當前枚舉類對象常量的名稱
    public class SeasonTest1 {public static void main(String[] args) {Season1[] s=Season1.values();for(Season1 e: s){System.out.println(e.toString()+","+e.getSeasonName()+","+e.getSeasonDesc());}System.out.println("****************");Thread.State[] values = Thread.State.values();for (Thread.State e:values) {System.out.println(e);}System.out.println("****************");Season1 s2=Season1.valueOf("SUMMER");System.out.println(s2.toString()+","+s2.getSeasonName()+","+s2.getSeasonDesc());} }//使用enum關鍵字定義枚舉類 enum Season1{//1.提供當前枚舉類的對象,多個對象之間用","隔開,末尾對象";"結束SPRING("春天","春暖花開"),SUMMER("夏天","夏日炎炎"),AUTUMN("秋天","秋高氣爽"),WINTER("冬天","冰天雪地");//2.聲明Season對象的屬性:private final修飾private final String seasonName;private final String seasonDesc;//3.私有化類的構造器,并給對象屬性賦值private Season1(String seasonName,String seasonDesc){this.seasonName = seasonName;this.seasonDesc = seasonDesc;}//4.獲取枚舉類對象的屬性public String getSeasonName() {return seasonName;}public String getSeasonDesc() {return seasonDesc;} }

    運行結果:

    SPRING,春天,春暖花開 SUMMER,夏天,夏日炎炎 AUTUMN,秋天,秋高氣爽 WINTER,冬天,冰天雪地 **************** NEW RUNNABLE BLOCKED WAITING TIMED_WAITING TERMINATED **************** SUMMER,夏天,夏日炎炎

    其它方法:

    6. 枚舉類實現接口

    • 和普通 Java 類一樣,枚舉類可以實現一個或多個接口
    • 若每個枚舉值在調用實現的接口方法呈現相同的行為方式,則只要統一實現該方法即可。
    • 若需要每個枚舉值在調用實現的接口方法呈現出不同的行為方式,則可以讓每個枚舉值分別來實現該方法
    public class SeasonTest2 {public static void main(String[] args) {Season1[] s=Season1.values();for(Season1 e :s ){System.out.print(e.toString()+","+e.getSeasonName()+","+e.getSeasonDesc()+",");e.show();}} }interface Info{void show(); }//使用enum關鍵字枚舉類 enum Season1 implements Info{//1.提供當前枚舉類的對象,多個對象之間用","隔開,末尾對象";"結束//可以給每一個枚舉類對象都實現一個show抽象方法SPRING("春天","春暖花開"){@Overridepublic void show() {System.out.println("春天在哪里?");}},SUMMER("夏天","夏日炎炎"){@Overridepublic void show() {System.out.println("夏天好熱!");}},AUTUMN("秋天","秋高氣爽"){@Overridepublic void show() {System.out.println("秋天不回來");}},WINTER("冬天","冰天雪地"){@Overridepublic void show() {System.out.println("大約在冬季");}};//2.聲明Season對象的屬性:private final修飾private final String seasonName;private final String seasonDesc;//2.私有化類的構造器,并給對象屬性賦值private Season1(String seasonName,String seasonDesc){this.seasonName = seasonName;this.seasonDesc = seasonDesc;}//4.獲取枚舉類對象的屬性public String getSeasonName() {return seasonName;}public String getSeasonDesc() {return seasonDesc;}// 公共的枚舉類對象方法 // @Override // public void show() { // System.out.println("這是一個季節"); // } }

    運行結果:

    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可以并列多個
    /** * @author 王xx * @version 1.0 * @see Math.java */ public class JavadocTest {/*** 程序的主方法,程序的入口* @param args String[] 命令行參數*/public static void main(String[] args) {}/*** 求圓面積的方法* @param radius double 半徑值* @return double 圓的面積*/public static double getArea(double radius){return Math.PI * radius * radius;} }

    示例二: 在編譯時進行格式檢查(JDK 內置的三個基本注解)

    • @Override: 限定重寫父類方法, 該注解只能用于方法
    • @Deprecated:用于表示所修飾的元素(類, 方法等)已過時。通常是因為所修飾的結構危險或存在更好的選擇
    • @SuppressWarnings: 抑制編譯器警告;(如果一些類,屬性,方法沒有使用,則編譯器會警告,友情提示警告你寫的代碼浪費空間資源)
    public class AnnotationTest{public static void main(String[] args) {@SuppressWarnings("unused")int a = 10;//泛型注解@SuppressWarnings({ "unused", "rawtypes" })ArrayList list = new ArrayList();}@Deprecatedpublic void print(){System.out.println("過時的方法");}@Overridepublic String toString() {return "重寫的toString方法()";} }

    示例三: 跟蹤 代碼依賴性,實現替代配置文件功能

    • 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
    • 注意:自定義注解必須配上注解的信息處理流程才有意義。
    //自定義注解 //自定義注解必須配上注解的信息處理流程(使用反射)才有意義。 public @interface MyAnnotation {String value() default "hello";//指定成員變量的初始值可使用` default `關鍵字 }

    使用自定義注解:

    @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中能夠得到方法參數的名稱。這會簡化標注在方法參數上的注解。

    可重復注解

    可重復注解示例:

  • 在MyAnnotation上聲明@Repeatable,成員值為MyAnnotations.class
  • MyAnnotations的@Target可以是MyAnnotation子集或完全一樣。
  • MyAnnotations的@Retention必須和MyAnnotation完全一樣。
  • 其它元注解,MyAnnotations也要和MyAnnotation保持一樣
  • //指定被該元 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"; } //指定被該元 Annotation 修飾的 Annotation 類將被javadoc 工具提取成文檔 @Documented //子類可以繼承父類類級別的Annotation @Inherited //指定該 Annotation 的生命周期 @Retention(RetentionPolicy.RUNTIME) //指定被修飾的 Annotation 能用于修飾哪些程序元素 @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) public @interface MyAnnotations {MyAnnotation[] value(); }

    類型注解

    • 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大杂烩的全部內容,希望文章能夠幫你解決所遇到的問題。

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