JavaSE : 注解 Annotation

注解

Java中的注解(Annotation)是一種元數據形式,用于向編譯器或JVM提供有關程序元素(如類、方法、變量、參數和包)的附加信息。注解不會直接影響程序的行為或結構,但它們可以被編譯器、開發工具或運行時環境用于生成代碼、進行驗證、執行處理或提供信息。以下是關于Java注解的幾個關鍵點:

1. 注解的種類

1.1.內置標準注解

  • @Override:指示一個方法覆蓋了超類中的方法。
  • @Deprecated:標記已過時的元素,建議不再使用。
  • @SuppressWarnings:抑制編譯器警告。

1.2.元注解:給注解用的注解

用于創建自定義注解的注解,包括:

1.2.1.@Retention

指定注解保留策略(解析時間),如RetentionPolicy.SOURCE(只保留在源碼中)、RetentionPolicy.CLASS(保留在class文件中)或RetentionPolicy.RUNTIME(運行時可通過反射訪問)。

1.2.1.1. SOURCE : 編譯時(Compile Time)

編譯時解析的注解在源代碼被編譯成字節碼時被處理。這些注解主要用于生成額外的代碼、檢查代碼的正確性或進行其他靜態分析。例如,@Override, @Deprecated, 和一些編譯器使用的注解如Lombok的@Data就是在編譯時期被解析的。編譯器或注解處理器(如APT, Annotation Processing Tool)會讀取這些注解并據此執行相應的操作。

1.2.1.2.CLASS : 類加載時(Class Load Time)

這類注解在類被加載到Java虛擬機(JVM)時被解析。例如,一些框架或庫會在類加載階段利用這些注解來配置類的行為,如Spring框架使用@Component, @Service, @Autowired等注解來實現依賴注入和bean的裝配,這些注解會在應用上下文初始化,即類加載時被解析和處理。

1.2.1.3.RUNTIME : 運行時(Runtime)

運行時解析的注解在應用程序運行過程中可以被讀取和處理。這意味著注解信息在程序執行期間始終可用,可以通過反射API來訪問這些注解。例如,@Retention(RetentionPolicy.RUNTIME)注解的那些注解可以在程序運行時通過反射被檢測到,常用于自定義注解處理、日志記錄、權限控制等場景。

1.2.2.@Target

指定注解可以應用到哪些程序元素上。

它接受一個ElementType類型的枚舉值數組作為參數,ElementType枚舉定義了一系列可能的目標元素類型。以下是ElementType的一些主要選項:

  1. ElementType.TYPE: 類、接口(包括注解類型)或枚舉聲明。
  2. ElementType.FIELD: 類或接口中的字段聲明(包括枚舉常量)。
  3. ElementType.METHOD: 類或接口中的方法聲明。
  4. ElementType.PARAMETER: 方法參數聲明。
  5. ElementType.CONSTRUCTOR: 類的構造函數聲明。
  6. ElementType.LOCAL_VARIABLE: 本地變量聲明。
  7. ElementType.ANNOTATION_TYPE: 另一個注解的聲明。
  8. ElementType.PACKAGE: 包聲明。
  9. ElementType.TYPE_PARAMETER: 類型參數聲明(Java 8及以后版本)。
  10. ElementType.TYPE_USE: 任何類型使用的地方,如泛型參數、類型轉換、靜態成員的類型等(Java 8及以后版本)。

1.2.3.@Documented

指示該注解應被包含在生成的API文檔中。

1.2.4.@Inherited

允許子類繼承父類上的注解。

1.2.5.@Repeatable

自Java 8起,允許同一注解在同一聲明上多次使用。

1.3.自定義注解

開發者可以定義自己的注解,通過@interface關鍵字實現,用于滿足特定的編程需求或框架集成。

public @interface MyAnnotation {}

1.3.1.注解的參數

定義注解參數

  1. 參數類型:注解參數必須是基本類型、String、Class、枚舉類型、注解類型或者這些類型的數組。不能使用其他復雜類型如自定義類作為參數。

  2. 默認值:每個注解參數都可以有一個默認值,如果沒有提供默認值且該參數又是必需的,則在使用注解時必須顯式指定參數值。

  3. 參數命名:參數命名遵循Java的標識符規則,通常采用小駝峰命名法。

示例定義

public @interface MyAnnotation {String name() default "";      // 默認值為空字符串int age();                    // 必須提供值,沒有默認值Class<?> clazz() default Object.class; // 默認值為Object類ElementType[] targets();       // 參數可以是數組類型
}

使用注解參數

在應用注解時,通過參數名指定參數值,如果是數組類型的參數,可以使用花括號 {} 來包裹多個值。

@MyAnnotation(name = "Alice", age = 25, clazz = String.class, targets = {ElementType.FIELD, ElementType.METHOD})
public class MyClass {// ...
}

特殊參數類型

  • Class類型參數:允許指定一個類或接口類型。
  • 枚舉類型參數:限制參數為預定義的一組值。
  • 注解類型參數:允許注解作為參數,用于嵌套注解的情況。
  • 數組類型參數:支持傳遞多個相同類型的值,如上面的targets參數。

1.3.2.value參數

在Java注解中,value是一個特殊的參數名。當一個注解只有一個參數,并且該參數名為value時,你可以省略參數名直接指定值。這種設計讓注解的使用更加簡潔易讀。下面是具體說明和示例:

特殊之處

  • 默認識別:如果一個注解僅定義了一個參數,并且這個參數的名字是value,那么在使用該注解時,可以直接寫值而不必指定參數名。編譯器會自動將這個值賦給value參數。
  • 多參數注解中的value : 即使一個注解定義了多個參數,如果其中包含名為value的參數,你仍然可以在只有一個值需要傳遞時省略value=。但是,如果有多個值需要指定,則所有參數都必須明確指出參數名。

示例定義

public @interface MySingleValueAnnotation {String value(); // 注意這里只有一個名為value的參數
}

使用示例

@MySingleValueAnnotation("Some text") // 直接寫值,不需要寫value=
public class MyClass {// ...
}// 對于非字符串或基本類型,同樣適用
@MySingleValueAnnotation(123) // 假設value參數類型為int
public void myMethod() {// ...
}

2.訪問注解信息

在Java中,通過反射處理注解是一種常見的做法,主要用于在運行時 ( 即使用@Retention(RUNTIME)定義的注解 ) 動態地檢查和操作那些被注解標記的類、方法、字段等元素。以下是一些基本步驟和示例,展示如何使用反射來獲取和使用注解信息:

2.1. 獲取注解實例

首先,你需要獲取到你想要檢查的類、方法或字段的 Class 對象。之后,可以使用這個 Class 對象提供的幾個方法來檢查和獲取注解:

  • isAnnotationPresent(Class<? extends Annotation> annotationClass):檢查是否具有指定類型的注解。
  • getAnnotation(Class<? extends Annotation> annotationClass):獲取指定類型的注解實例,如果沒有則返回 null
  • getAnnotations()getDeclaredAnnotations():獲取所有注解或直接聲明的注解數組。

示例:獲取類上的注解

假設我們有一個自定義的注解 @MyAnnotation,并應用到了某個類 MyClass 上。

@MyAnnotation(value = "Hello, World!")
public class MyClass {// ...
}

獲取這個類上的 MyAnnotation 實例:

Class<MyClass> clazz = MyClass.class;
if (clazz.isAnnotationPresent(MyAnnotation.class)) {MyAnnotation myAnnotation = clazz.getAnnotation(MyAnnotation.class);System.out.println("注解的值: " + myAnnotation.value());
}

示例:獲取方法上的注解

同樣的,如果 MyAnnotation 應用于某個方法上:

public class MyClass {@MyAnnotation(value = "Method Annotation")public void myMethod() {// ...}
}

獲取方法上的注解:

Method method = MyClass.class.getMethod("myMethod");
if (method.isAnnotationPresent(MyAnnotation.class)) {MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);System.out.println("方法注解的值: " + myAnnotation.value());
}

示例:基于注解值動態操作

根據注解的信息,你可以進一步決定程序的執行邏輯,例如:

if (myAnnotation != null && "Special Value".equals(myAnnotation.value())) {// 執行特定的操作
} else {// 執行默認操作
}

注意事項

  • 確保你的注解有運行時保留策略 (@Retention(RetentionPolicy.RUNTIME)),否則它們不會在運行時可見。
  • 當使用反射處理注解時,考慮性能影響,特別是在頻繁操作或大型項目中。
  • 利用注解可以極大地增強代碼的靈活性和可配置性,但過度使用或設計不當也可能導致代碼難以理解和維護。

3. 注解的作用

  • 提供配置信息:注解可以替代XML或其他外部配置文件,直接在代碼中提供配置細節。
  • 代碼文檔化:增強代碼的自我解釋性,提供方法用途、參數意義等信息。
  • 編譯時檢查:通過編譯時注解處理器進行類型安全檢查、格式驗證等。
  • 框架集成:許多Java框架(如Spring)使用注解來配置依賴注入、事務管理等。
  • 代碼生成:一些工具可以讀取注解并據此自動生成代碼片段,如序列化/反序列化代碼、getter/setter等。
  • 運行時處理:通過反射,應用程序可以在運行時發現和處理注解,實現動態行為。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/13675.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/13675.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/13675.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Apache CXF Aegis databinding SSRF 高危漏洞修復

一、漏洞修復 Apache CXF Aegis databinding SSRF漏洞 Spring Web UriComponentsBuilder URL解析不當漏洞 二、修復步驟 1、Apache CXF Aegis databinding SSRF漏洞修復 步驟&#xff1a; 進入服務器搜索 databinding find -name *databinding* 發現版本是3.1.6 果斷…

數據結構~~帶環鏈表的環開始的節點位置**兩種方法

1.帶環鏈表環開始的位置 &#xff08;1&#xff09;上面的這個測試用例使用的是包含了4個節點的帶環鏈表&#xff0c;我們要找的就是鏈表里面的環開始的節點的位置&#xff0c;拿這個測試用例而言&#xff0c;就是2這個節點&#xff0c;從這個節點開始&#xff0c;我們的鏈表就…

【第16章】MyBatis-Spring之SqlSession

文章目錄 前言一、SqlSessionTemplate1. 創建2. 使用3. 批量操作3.1 創建SqlSessionTemplate3.2 service3.3 controller 二、SqlSessionDaoSupport總結 前言 在 MyBatis 中&#xff0c;你可以使用 SqlSessionFactory 來創建 SqlSession。 一旦你獲得一個 session 之后&#xf…

源碼部署EFK

目錄 資源列表 基礎環境 關閉防護墻 關閉內核安全機制 修改主機名 添加hosts映射 一、部署elasticsearch 修改limit限制 部署elasticsearch 修改配置文件 單節點 集群(3臺節點集群為例) 啟動 二、部署filebeat 部署filebeat 添加配置文件 啟動 三、部署kiban…

單點登錄【demo】

前言 2023-07-29 15:44:56 公開發布于 2024-5-22 00:04:56 單點登錄【demo】 以下是 Java 實現單點登錄的示例代碼&#xff1a; 單點登錄&#xff08;Single Sign-On&#xff0c;SSO&#xff09;是一種身份認證和授權機制&#xff0c;可以使用戶在多個應用程序或系統之間使…

SQL常用基礎語句(一)-- FGHIJ開頭

GROUP BY GROUP BY語法可以根據給定數據列的每個成員對查詢結果進行分組統計&#xff0c;最終得到一個分組匯總表。在GROUP BY子句后面包含了一個HAVING子句&#xff0c;HAVING類似于WHERE&#xff0c;&#xff08;唯一的差別是WHERE過濾行&#xff0c;HAVING過濾組&#xff0…

【C/C++筆試練習】TCP、IP廣播、ARP協議、IP路由器、MAC協議、三次握手、TCP/IP、子網劃分年、會抽獎、抄送列表

文章目錄 C/C筆試練習選擇部分&#xff08;1&#xff09;TCP&#xff08;2&#xff09;IP廣播&#xff08;3&#xff09;ARP協議&#xff08;4&#xff09;IP路由器&#xff08;5&#xff09;MAC協議&#xff08;6&#xff09;三次握手&#xff08;7&#xff09;TCP/IP&#xf…

PHP在線制作表白網源碼

PHP在線制作表白網源碼&#xff0c;送女友個驚喜吧&#xff0c;無數據庫&#xff0c;上傳就能用&#xff0c;后臺/admin&#xff0c;賬號密碼都是admin 百度網盤&#xff1a;https://pan.baidu.com/s/1rbD2_8IsP9UPLK-cdgEXfA?pwdre59

AWS安全性身份和合規性之Secrets Manager

AWS Secrets Manager是一項AWS托管的服務&#xff0c;用于安全地存儲、管理和輪轉敏感信息&#xff0c;如數據庫密碼、API密鑰、OAuth令牌等。AWS Secrets Manager助您在整個生命周期內輕松管理、檢索和輪換數據庫憑證、API密鑰和其他密鑰。 關鍵詞&#xff1a;集中管理、加密…

sql使用加和進行合并去重并提升速率

背景 有三張表ltd1 、ltd0051和、ltd0011ltd1作為主表&#xff0c;左關聯 ltd0051和ltd0011如果ltd0051有兩條重復數據、td0011有兩條重復數據&#xff0c;左關聯之后就會得到4條&#xff0c;同時ltd0051和ltd0011這兩條數據都是正確&#xff0c;基于主鍵我們需要將兩個相同主鍵…

【全開源】AJAX家政上門服務系統小程序自營+多商家(高級授權)+獨立端

基于FastAdmin和原生微信小程序開發的一款同城預約、上門服務、到店核銷家政系統&#xff0c;用戶端、服務端(高級授權)、門店端(高級授權)各端相互依賴又相互獨立&#xff0c;支持選擇項目、選擇服務人員、選擇門店多種下單方式&#xff0c;支持上門服務和到店核銷兩種服務方式…

深入理解數倉開發(一)數據技術篇之日志采集

前言 今天開始重新回顧電商數倉項目&#xff0c;結合《阿里巴巴大數據之路》和尚硅谷的《劍指大數據——企業級電商數據倉庫項目實戰 精華版》來進行第二次深入理解學習。之前第一次學習數倉&#xff0c;雖然盡量放慢速度力求深入理解&#xff0c;但是不可能一遍掌握&#xff0…

我在去哪兒薅到了5塊錢火車票代金券,速薅

哈哈&#xff0c;親愛的薅羊毛小伙伴們&#xff01; 剛剛在去哪兒大佬那兒發現了一個超級薅羊毛福利&#xff01;我只花了短短兩分鐘&#xff0c;就搞到了一張5塊錢火車票代金券&#xff0c;簡直是天上掉餡餅的節奏啊&#xff01; 話不多說&#xff0c;薅羊毛的姿勢給你們擺好…

代碼隨想錄算法訓練營第十六天(py)| 二叉樹 | 104.二叉樹的最大深度、111.二叉樹的最小深度、222.完全二叉樹的節點個數

104.二叉樹的最大深度 給定一個二叉樹 root &#xff0c;返回其最大深度。 二叉樹的 最大深度 是指從根節點到最遠葉子節點的最長路徑上的節點數。 思路1 迭代法 層序遍歷 層序遍歷的思路很簡單&#xff0c;其結果本來就是按層數記錄的&#xff0c;只需返回結果的長度皆可。…

【C語言回顧】聯合和枚舉

前言1. 聯合體1.1 聯合體的聲明1.2 聯合體的特點1.3 聯合體的使用 2. 枚舉2.1 枚舉的聲明2.2 枚舉的特點2.3 枚舉的使用 結語 #include<GUIQU.h> int main { 上期回顧: 【C語言回顧】結構體 個人主頁&#xff1a;C_GUIQU 專欄&#xff1a;【C語言學習】 return 一鍵三連;…

解決法律條文的錄入前判斷發條沖突的需求;怎么選擇NLPModel?怎么使用模型?

要在NLPModel類中實現法律條文的沖突檢測功能&#xff0c;可以使用BERT模型來計算句子相似度。以下是詳細的步驟&#xff0c;包括如何選擇模型、訓練模型以及使用模型。 選擇NLP模型 根據你的需求&#xff0c;BERT&#xff08;Bidirectional Encoder Representations from Tra…

Linux多線程系列三: 生產者消費者模型,信號量使用,基于阻塞隊列和環形隊列的這兩種生產者消費者代碼的實現

Linux多線程系列三: 生產者消費者模型,信號量,基于阻塞隊列和環形隊列的這兩種生產者消費者代碼的實現 一.生產者消費者模型的理論1.現實生活中的生產者消費者模型2.多線程當中的生產者消費者模型3.理論 二.基于阻塞隊列的生產者消費者模型的基礎代碼1.阻塞隊列的介紹2.大致框架…

別說廢話!說話說到點上,項目高效溝通的底層邏輯揭秘

假設你下周要在領導和同事面前匯報項目進度&#xff0c;你會怎么做&#xff1f;很多人可能會去網上搜一個項目介紹模板&#xff0c;然后按照模板來填充內容。最后&#xff0c;匯報幻燈片做了 80 頁&#xff0c;自己覺得非常充實&#xff0c;但是卻被領導痛批了一頓。 這樣的境…

樹的非遞歸遍歷(層序)

層序是采用隊列的方式來遍歷的 就比如說上面這顆樹 他層序的就是&#xff1a;1 24 356 void LevelOrder(BTNode* root) {Que q;QueueInit(&q);if (root){QueuePush(&q, root);}while (!QueueEmpty(&q)){BTNode* front QueueFront(&q);QueuePop(&q);print…

簡析網絡風險量化的價值與應用實踐,如何構建網絡風險預防架構

網絡風險量化能夠讓公司董事會和高管層看清當前的網絡安全風險格局&#xff1b;它還將使安全團隊能夠在業務需求的背景下做出網絡安全決策&#xff0c;幫助組織確定哪些風險對業務構成最大的威脅&#xff0c;以及預期的經濟損失將是什么。 隨著網絡攻擊手段的日益多樣化和復雜…