Java中的注解技術講解

Java中的注解(Annotation)是一種在代碼中嵌入元數據的機制,不直接參與業務邏輯,而是為編譯器、開發工具以及運行時提供額外的信息和指導。下面我們將由淺入深地講解Java注解的概念、實現原理、各種應用場景,并通過代碼示例幫助理解。


1. 注解的基本概念

注解類似于“標簽”,可以附加在類、方法、屬性、參數、局部變量等位置,用于說明該代碼元素的特殊意義或行為。注解本身不會影響程序的運行,但可以被編譯器、工具或通過反射讀取并執行相應的處理邏輯。

  • 作用:
    • 提供元數據: 指示編譯器進行檢查(如@Override標識的方法必須是重寫父類方法)。
    • 代碼生成與校驗: 一些工具可以根據注解生成額外代碼或者配置文件。
    • 運行時行為控制: 框架通過讀取注解信息動態實現依賴注入、事務管理等功能(例如Spring、JUnit等)。

2. 常見內置注解與使用場景

Java提供了一些內置注解,開發者無需額外定義,可直接使用:

  1. @Override

    • 用于標注一個方法是重寫父類或接口中的方法。
    • 示例:
      public class Parent {public void display() {System.out.println("Parent display");}
      }public class Child extends Parent {@Overridepublic void display() {System.out.println("Child display");}
      }
      
    • 作用: 避免因方法簽名錯誤而導致沒有成功重寫父類方法。
  2. @Deprecated

    • 表示一個方法、類或字段已過時,不建議繼續使用。
    • 示例:
      public class Example {@Deprecatedpublic void oldMethod() {System.out.println("This method is deprecated");}
      }
      
    • 作用: 編譯時會給出警告,鼓勵開發者采用新的實現方式。
  3. @SuppressWarnings

    • 用于抑制編譯器特定的警告信息。
    • 示例:
      @SuppressWarnings("unchecked")
      public void useLegacyCode() {List list = new ArrayList();// 這里可能涉及未檢查的類型轉換
      }
      

3. 自定義注解

Java允許開發者定義自己的注解,可以通過元注解(Meta-Annotation)來指定注解的行為。

3.1 定義自定義注解

自定義注解通常使用@interface關鍵字定義,并結合以下元注解設置行為:

  • @Retention:指定注解的生命周期(SOURCE、CLASS或RUNTIME)。
    • RUNTIME的注解能在運行時通過反射讀取。
  • @Target:定義注解可以應用到哪些元素(例如METHOD、FIELD、TYPE等)。
  • @Inherited:允許子類繼承父類的注解(只對類有效)。
  • @Documented:將注解包含在Javadoc中。

示例:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;// 該注解在運行時可見,并且只能應用于方法和類
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface MyAnnotation {// 定義一個具有默認值的屬性String value() default "default value";// 定義一個無默認值的屬性,使用時必須賦值int number();
}

3.2 使用自定義注解

使用自定義注解時,就像使用內置注解一樣,直接在代碼元素上加上即可。

示例:

@MyAnnotation(number = 10, value = "ExampleClass")
public class ExampleClass {@MyAnnotation(number = 5, value = "ExampleMethod")public void exampleMethod() {System.out.println("Executing example method");}public static void main(String[] args) {ExampleClass obj = new ExampleClass();obj.exampleMethod();}
}

3.3 通過反射讀取注解

注解最強大的功能之一便是能在運行時通過反射讀取它們的信息,從而根據注解進行對應的處理。

示例:

import java.lang.reflect.Method;public class AnnotationProcessor {public static void main(String[] args) {try {// 獲取類的字節碼Class<?> clazz = Class.forName("ExampleClass");// 檢查類上是否有MyAnnotationif (clazz.isAnnotationPresent(MyAnnotation.class)) {MyAnnotation classAnnotation = clazz.getAnnotation(MyAnnotation.class);System.out.println("Class Annotation: value = " + classAnnotation.value()+ ", number = " + classAnnotation.number());}// 遍歷所有方法for (Method method : clazz.getDeclaredMethods()) {if (method.isAnnotationPresent(MyAnnotation.class)) {MyAnnotation methodAnnotation = method.getAnnotation(MyAnnotation.class);System.out.println("Method " + method.getName() + " Annotation: value = " + methodAnnotation.value() + ", number = " + methodAnnotation.number());}}} catch (ClassNotFoundException e) {e.printStackTrace();}}
}

此例演示了如何檢查類和方法上是否存在MyAnnotation注解,并輸出相應的屬性值。


4. 元注解(Meta-Annotations)的深入理解

元注解用于修飾其他注解,本質上是為注解定義行為的工具。主要元注解包括:

  1. @Retention

    • 作用: 定義注解的保留策略
    • 策略:
      • RetentionPolicy.SOURCE:注解僅在源碼中存在,編譯器會忽略,不會寫入.class文件。
      • RetentionPolicy.CLASS:注解會被編譯到class文件,但運行時不保留(默認策略)。
      • RetentionPolicy.RUNTIME:注解不僅被編譯到class文件,而且在運行時通過反射可獲取。
  2. @Target

    • 作用: 限定注解能夠應用的元素類型,如類、方法、字段、參數等。
    • 示例:
      @Target(ElementType.METHOD)
      public @interface MethodAnnotation { }
      
  3. @Inherited

    • 作用: 允許子類繼承父類的注解(僅適用于類)。
    • 示例:
      @Inherited
      @Retention(RetentionPolicy.RUNTIME)
      public @interface InheritableAnnotation { }@InheritableAnnotation
      public class Parent { }public class Child extends Parent { }
      // Child類同樣具備InheritableAnnotation注解信息
      
  4. @Documented

    • 作用: 表明使用該注解的信息應被包含在Javadoc中。

5. 注解的高級使用場景

5.1 框架配置與依賴注入

許多現代框架利用注解簡化配置。例如,Spring使用注解來標識組件、注入依賴和配置事務:

  • 示例:
    @Service
    public class UserService {@Autowiredprivate UserRepository userRepository;
    }
    
    這里@Service@Autowired注解告訴Spring這是一個服務類并需要自動注入相應的依賴。

5.2 單元測試(JUnit)

JUnit使用注解標識測試方法,使得測試代碼不依賴外部配置:

  • 示例:
    import org.junit.Test;
    import static org.junit.Assert.assertEquals;public class CalculatorTest {@Testpublic void testAdd() {Calculator calc = new Calculator();int result = calc.add(5, 3);assertEquals(8, result);}
    }
    
    @Test注解標注了測試方法,JUnit框架可以自動識別和執行這些測試方法。

5.3 日志記錄與AOP(面向切面編程)

通過自定義注解與AOP相結合,可以在方法執行前后自動記錄日志或執行其他橫切邏輯。

  • 示例:定義日志注解
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface Log {String value() default "";
    }
    
  • 示例:使用AOP切面讀取注解信息
    @Aspect
    @Component
    public class LogAspect {@Around("@annotation(logAnnotation)")public Object logExecution(ProceedingJoinPoint joinPoint, Log logAnnotation) throws Throwable {System.out.println("Start executing: " + joinPoint.getSignature().getName() + " with log: " + logAnnotation.value());Object result = joinPoint.proceed();System.out.println("Finished executing: " + joinPoint.getSignature().getName());return result;}
    }
    
    在這里,任何標注了@Log注解的方法都會在執行前后打印日志信息。

5.4 編譯時檢查和代碼生成

注解處理器(Annotation Processor)允許在編譯期間對源代碼進行掃描和處理,從而自動生成代碼、配置文件或檢查不符合規范的地方。常見的例子如:Lombok 就是通過注解處理器來生成setter/getter方法,減少樣板代碼。

  • 示例:自定義注解處理器基本流程
    開發者可以實現javax.annotation.processing.AbstractProcessor,并通過@SupportedAnnotationTypes聲明支持的注解:
    @SupportedAnnotationTypes("com.example.MyAnnotation")
    @SupportedSourceVersion(SourceVersion.RELEASE_8)
    public class MyAnnotationProcessor extends AbstractProcessor {@Overridepublic boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {for (Element element : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {// 執行自定義處理邏輯,如代碼生成或檢查代碼結構}return true;}
    }
    
    使用注解處理器的好處是可以在編譯期暴露問題,而不必等到運行時才發生異常。

6. 總結

  • 入門: 注解本質上是為代碼添加元數據,能為編譯器、工具或框架提供指導信息,常見的如@Override@Deprecated@SuppressWarnings
  • 自定義注解: 利用@interface關鍵字和元注解(如@Retention@Target)可以定義適用于特定場景的自定義注解,并結合反射技術實現動態處理。
  • 高級應用: 在框架配置、依賴注入、單元測試、AOP日志記錄以及編譯時代碼生成等場景中,注解均發揮著非常重要的作用,極大地提高了代碼的可維護性和擴展性。

通過上述講解和示例代碼,能更全面、深入地理解Java中注解的概念和應用場景。這種機制不僅在Java EE和Spring等框架中被廣泛應用,而且也成為現代Java開發中不可或缺的工具之一。

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

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

相關文章

京東與喜茶關系破裂:切斷所有合作 禁止進入辦公場所

快科技4月10日消息&#xff0c;據報道&#xff0c;京東集團近日被曝出內部下發全員禁令&#xff0c;全面封殺喜茶產品進入辦公區域。 據知情人士透露&#xff0c;京東人力行政部門發布的通知明確規定&#xff1a;全國各職場禁止與喜茶品牌開展任何形式的合作&#xff1b;員工不…

+++++背到厭倦。持續更新

Spring IoC 的工作流程: 讀取 BeanDefinition: Spring 容器啟動時&#xff0c;會讀取 Bean 的配置信息 (例如 XML 配置文件、注解或 Java 代碼)&#xff0c;并將這些配置信息轉換為 BeanDefinition 對象。創建 Bean 實例: 根據 BeanDefinition 中的信息&#xff0c;Spring 容器…

如何在Git歷史中抹掉中文信息并翻譯成英文

如何在Git歷史中抹掉中文信息并翻譯成英文 在軟件開發和版本控制領域&#xff0c;維護一個清晰、一致的代碼歷史記錄是至關重要的。然而&#xff0c;有時我們可能會遇到需要修改歷史提交的情況&#xff0c;比如刪除敏感信息或修正錯誤。本文將詳細探討如何在Git歷史中抹掉中文…

21 天 Python 計劃:MySQL中DML與權限管理

文章目錄 前言一、介紹二、MySQL數據操作&#xff1a;DML2.1 插入數據&#xff08;INSERT&#xff09;2.1.1 插入完整數據&#xff08;順序插入&#xff09;2.1.2 指定字段插入數據2.1.3 插入多條記錄2.1.4 插入查詢結果 2.2 更新數據&#xff08;UPDATE&#xff09;2.3 刪除數…

微信小程序 -- 原生封裝table

文章目錄 table.wxmltable.wxss注意 table.js注意 結果數據結構 最近菜鳥做微信小程序的一個查詢功能&#xff0c;需要展示excel里面的數據&#xff0c;但是菜鳥找了一圈&#xff0c;也沒發現什么組件庫有table&#xff0c;畢竟手機端好像確實不太適合做table&#xff01; 菜鳥…

LangChain-輸出解析器 (Output Parsers)

輸出解析器是LangChain的重要組件&#xff0c;用于將語言模型的原始文本輸出轉換為結構化數據。本文檔詳細介紹了輸出解析器的類型、功能和最佳實踐。 概述 語言模型通常輸出自然語言文本&#xff0c;但在應用開發中&#xff0c;我們經常需要將這些文本轉換為結構化的數據格式…

【安全】加密算法原理與實戰

為了理解SSL/TLS原理&#xff0c;大家需要掌握一些加密算法的基礎知識。當然&#xff0c;這不是為了讓大家成為密碼學專家&#xff0c;所以只需對基礎的加密算法有一些了解即可。基礎的加密算法主要有哈希&#xff08;Hash&#xff0c;或稱為散列&#xff09;?、對稱加密(Symm…

MySQL 優化教程:讓你的數據庫飛起來

文章目錄 前言一、數據庫設計優化1. 合理設計表結構2. 范式化與反范式化3. 合理使用索引 二、查詢優化1. 避免使用 SELECT *2. 優化 WHERE 子句3. 優化 JOIN 操作 三、服務器配置優化1. 調整內存分配2. 調整并發參數3. 優化磁盤 I/O 四、監控與分析1. 使用 EXPLAIN 分析查詢語句…

LangChain4j(1):初步認識Java 集成 LLM 的技術架構

LangChain 作為構建具備 LLM 能力應用的框架&#xff0c;雖在 Python 領域大放異彩&#xff0c;但 Java 開發者卻只能望洋興嘆。LangChain4j 正是為解決這一困境而誕生&#xff0c;它旨在借助 LLM 的強大效能&#xff0c;增強 Java 應用&#xff0c;簡化 LLM 功能在Java應用中的…

Linux服務器安裝百度飛槳3.0(pip docker)

Linux安裝部署百度飛槳3.0 1.官方文檔指引2.確認服務器型號2.1 確認Python版本2.2 確認pip是否安裝2.3 確認計算平臺 3.本機安裝&#xff08;基于通過 pip 安裝&#xff09;3.1 下載安裝 PaddlePaddle3.2 安裝PaddleX3.2.1 安裝PaddleX3.2.2 命令行規范3.2.3 運行示例3.2.4 查看…

Spring Boot 自動加載流程詳解

前言 Spring Boot 是一個基于約定優于配置理念的框架&#xff0c;它通過自動加載機制大大簡化了開發者的配置工作。本文將深入探討 Spring Boot 的自動加載流程&#xff0c;并結合源碼和 Mermaid 圖表進行詳細解析。 一、Spring Boot 自動加載的核心機制 Spring Boot 的自動加…

2025年危化品安全管理人員備考指南|智能題庫+核心考點解析

作為危化品生產單位安全管理人員&#xff08;主要負責人&#xff09;&#xff0c;考試內容主要涵蓋三大模塊&#xff1a; 法律法規體系 《安全生產法》修訂要點&#xff08;2023版&#xff09; 危險化學品重大危險源辨識標準&#xff08;GB 18218&#xff09; 最新《化工過…

如何優雅使用 ReentrantLock 進行加解鎖:避免常見坑點,提高代碼可維護性

引言&#xff1a;鎖的基本概念和問題 在多線程編程中&#xff0c;為了確保多個線程在訪問共享資源時不會發生沖突&#xff0c;我們通常需要使用 鎖 來同步對資源的訪問。Java 提供了不同的鎖機制&#xff0c;其中 ReentrantLock 是一種最常用且功能強大的鎖&#xff0c;它屬于…

Redhat紅帽 RHCE8.0認證體系課程

課程大小&#xff1a;7.7G 課程下載&#xff1a;https://download.csdn.net/download/m0_66047725/90546064 更多資源下載&#xff1a;關注我 紅帽企業 Linux 系統的管理技能已經成為現代數據中心的核心競爭力。 Linux 在支持混合云、跨物理服務器、虛機、私有云和公共云計…

Shell腳本編程

目錄 1. Shell腳本概述 什么是Shell&#xff1f; Shell的作用 常見的Shell類型 2. 環境搭建與安裝 Linux系統 macOS系統 Windows系統 3.安裝并配置Zsh&#xff08;macOS/Linux&#xff09; 4. Shell基礎語法 變量與數據類型 輸入交互 5. Shell腳本進階 進程管理 …

學生管理系統(Python)

運行結果&#xff1a; 源代碼&#xff1a; """ 項目&#xff1a;類似于學生管理系統---增刪改查 """ #封裝一個學生類 import random class Student: def __init__(self,stuid,name,score): self.stuid stuid self.name name self.score …

電商素材革命:影刀RPA魔法指令3.0驅動批量去水印,實現秒級素材凈化

本文 去除水印實操視頻展示電商圖片水印處理的困境?影刀 RPA 魔法指令 3.0 強勢登場?利用魔法指令3.0兩步實現去除水印操作關于影刀RPA 去除水印實操視頻展示 我們這里選擇了4張小紅書里面比較帥氣的圖片&#xff0c;但凡用過小紅書的都知道&#xff0c;小紅書右下角是會有小…

Seq2Seq - GRU補充講解

nn.GRU 是 PyTorch 中實現門控循環單元&#xff08;Gated Recurrent Unit, GRU&#xff09;的模塊。GRU 是一種循環神經網絡&#xff08;RNN&#xff09;的變體&#xff0c;用于處理序列數據&#xff0c;能夠更好地捕捉長距離依賴關系。 ?重點掌握輸入輸出部分輸入張量&#…

設計模式-觀察者模式和發布訂閱模式區別

文章目錄 其他不錯的文章 二者有類似的地方&#xff0c;也有區別。 引用的文章說的已經比較清楚了&#xff0c;這里只列出對比圖。 對比點觀察者模式發布訂閱模式中間人角色無事件中心&#xff0c;觀察者直接訂閱目標有事件中心&#xff0c;發布者與訂閱者通過事件中心通信關系…

【SQL】基于多源SQL 去重方法對比 -- 精華版

【SQL】基于SQL 去重方法對比 -- 精華版 一、引言二、基于SQL去重方法完整對比1. MySQL去重方法及優劣勢1.1 ?DISTINCT關鍵字1.2 GROUP BY子句1.3 UNION系列操作1.4 子查詢 自關聯 2. Hive去重方法及優劣勢2.1 DISTINCT關鍵字2.2 ?GROUP BY子句2.3 ?ROW_NUMBER窗口函數2.4 …