Java學習——day24(反射進階:注解與動態代理)

文章目錄

  • 1. 反射與注解
  • 2. 動態代理
  • 3. 實踐:編寫動態代理示例
  • 4. 注解定義與使用
  • 5. 動態代理
  • 6. 小結與思考

1. 反射與注解

  • 注解:注解是 Java 提供的用于在代碼中添加元數據的機制。它不會影響程序的執行,但可以在運行時通過反射獲取和處理。
  • 反射讀取注解:
    • 通過 Class、Method、Field 等反射 API 獲取注解信息。
    • 注解可以用于類、方法、字段等。

2. 動態代理

  • 動態代理的概念:動態代理是 Java 提供的一種機制,可以在運行時創建接口的代理實例,并且可以在方法調用前后插入額外的操作。
  • 使用 Proxy 類:java.lang.reflect.Proxy 類提供了創建代理對象的靜態方法。
  • 代理接口:通過 InvocationHandler 接口來定義代理對象的行為。

3. 實踐:編寫動態代理示例

  • 創建一個接口,使用動態代理為其生成代理對象。
  • 在代理方法中加入日志打印,打印每個方法的調用時間。

4. 注解定義與使用

注解的定義通常采用 @interface 關鍵字,例如:

// 定義一個自定義注解
import java.lang.annotation.*;@Target(ElementType.METHOD) // 這個注解應用在方法上
@Retention(RetentionPolicy.RUNTIME) // 運行時可以反射獲取
public @interface Log {String value() default "日志記錄";
}

如何通過反射讀取注解:
假設有如下類及方法上使用了注解:

import java.lang.annotation.*;public class Example {// 應用自定義注解@Log(value = "執行sayHello方法")public void sayHello() {System.out.println("Hello, World!");}public static void main(String[] args) {try {// 獲取 sayHello 方法的 Class 對象Method method = Example.class.getMethod("sayHello");// 判斷該方法是否有 Log 注解if (method.isAnnotationPresent(Log.class)) {// 獲取注解的值Log log = method.getAnnotation(Log.class);System.out.println("注解內容: " + log.value());}// 調用方法method.invoke(new Example());} catch (Exception e) {e.printStackTrace();}}
}

輸出結果:

注解內容: 執行sayHello方法
Hello, World!

解釋:

  • @Log 注解定義了一個 value 屬性,在 sayHello() 方法上使用。
  • 通過反射獲取方法 sayHello,使用 isAnnotationPresent 判斷是否應用了注解,然后獲取注解并打印 value 屬性。

5. 動態代理

動態代理的原理

  • 動態代理是一種在運行時創建代理對象的技術。通過 java.lang.reflect.Proxy 類和 InvocationHandler 接口,Java 實現了動態代理機制。
  • 通過動態代理可以增強原對象的功能,比如記錄日志、權限控制等。

創建動態代理的基本步驟
1.定義接口:代理類需要實現接口。
2.實現 InvocationHandler:InvocationHandler 用于處理代理對象的方法調用。
3.使用 Proxy.newProxyInstance():創建代理對象。

示例:為某個接口創建代理對象,并在方法調用前后打印日志
1. 定義接口

public interface Person {void sayHello();void work();
}

2. 實現接口

public class PersonImpl implements Person {@Overridepublic void sayHello() {System.out.println("Hello from Person!");}@Overridepublic void work() {System.out.println("Person is working.");}
}

3. 創建 InvocationHandler 實現類

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class LoggingHandler implements InvocationHandler {private Object target;public LoggingHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 在方法執行前打印日志System.out.println("Method " + method.getName() + " is about to be called.");// 執行目標方法Object result = method.invoke(target, args);// 在方法執行后打印日志System.out.println("Method " + method.getName() + " was called.");return result;}
}

4. 使用 Proxy 創建代理對象

import java.lang.reflect.Proxy;public class DynamicProxyExample {public static void main(String[] args) {Person person = new PersonImpl(); // 創建目標對象// 創建代理對象Person proxyPerson = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(),new Class<?>[]{Person.class},new LoggingHandler(person));// 使用代理對象調用方法proxyPerson.sayHello();proxyPerson.work();}
}

輸出結果:

Method sayHello is about to be called.
Hello from Person!
Method sayHello was called.
Method work is about to be called.
Person is working.
Method work was called.

解釋:

  • 通過 Proxy.newProxyInstance() 創建了一個 Person 接口的代理對象。代理對象會調用 LoggingHandler 的 invoke 方法。
  • LoggingHandler 通過 method.invoke(target, args) 調用實際的目標方法,并在方法調用前后打印日志。

6. 小結與思考

1.反射與注解:

  • 注解是一個非常強大的元數據機制,可以在運行時動態地獲取類和方法的相關信息。常見應用包括框架開發、AOP(面向切面編程)等。
    2.動態代理:
  • 動態代理是面向切面編程中的一個核心技術,它允許我們在運行時動態地為接口生成代理,并對方法執行前后進行增強(如日志、權限控制等)。
  • 動態代理廣泛應用于 Java 框架,如 Spring 的 AOP(面向切面編程)。

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

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

相關文章

C++之nullptr

文章目錄 前言 一、NULL 1、代碼 2、結果 二、nullptr 1、代碼 2、結果 總結 前言 當我們談論空指針時,很難避免談及nullptr。nullptr是C++11引入的一個關鍵字,用來表示空指針。在C++中,空指針一直是一個容易引起混淆的問題,因為在早期版本的C++中,通常使用NULL來…

JavaScript惰性加載優化實例

這是之前的一位朋友的酒桌之談&#xff0c;他之前負責的一個電商項目&#xff0c;剛剛開發萬&#xff0c;首頁加載時間特別長&#xff0c;體驗很差&#xff0c;所以就開始排查&#xff0c;發現是在首頁一次性加載所有js導致的問題&#xff0c;這個問題在自己學習的時候并不明顯…

蘋果內購支付 Java 接口

支付流程&#xff0c;APP支付成功后 前端調用后端接口&#xff0c;后端接口將前端支付成功后拿到的憑據傳給蘋果服務器檢查&#xff0c;如果接口返回成功了&#xff0c;就視為支付。 代碼&#xff0c;productId就是蘋果開發者后臺提前設置好的 產品id public CommonResult<S…

數據庫中的數組: MySQL與StarRocks的數組操作解析

在現代數據處理中, 數組 (Array) 作為一種高效存儲和操作結構化數據的方式, 被廣泛應用于日志分析, 用戶行為統計, 標簽系統等場景. 然而, 不同數據庫對數組的支持差異顯著. 本文將以MySQL和StarRocks為例, 深入解析它們的數組操作能力, 并對比其適用場景. 文章目錄 一 為什么需…

LeetCode零錢兌換(動態規劃)

題目描述 給你一個整數數組 coins &#xff0c;表示不同面額的硬幣&#xff1b;以及一個整數 amount &#xff0c;表示總金額。 計算并返回可以湊成總金額所需的 最少的硬幣個數 。如果沒有任何一種硬幣組合能組成總金額&#xff0c;返回 -1 。 你可以認為每種硬幣的數量是無…

/sys/fs/cgroup/memory/memory.stat 關鍵指標說明

目錄 1. **total_rss**2. **total_inactive_file**3. **total_active_file**4. **shmem**5. **其他相關指標**總結 以下是/sys/fs/cgroup/memory/memory.stat文件中一些關鍵指標的詳細介紹&#xff0c;特別是與PostgreSQL相關的指標&#xff1a; 1. total_rss 定義&#xff1…

C++第14屆藍橋杯b組學習筆記

1. 日期統計 小藍現在有一個長度為 100100 的數組&#xff0c;數組中的每個元素的值都在 00 到 99 的范圍之內。數組中的元素從左至右如下所示&#xff1a; 5 6 8 6 9 1 6 1 2 4 9 1 9 8 2 3 6 4 7 7 5 9 5 0 3 8 7 5 8 1 5 8 6 1 8 3 0 3 7 9 2 7 0 5 8 8 5 7 0 9 9 1 9 4 4…

[Effective C++]條款28:避免返回handles指向對象內部成分

. 在C中&#xff0c;返回指向對象內部成分的引用&#xff08;handles&#xff09;可能會導致封裝性降低和對象空懸問題。為了避免這些問題&#xff0c;可以通過返回const引用來限制對內部數據的修改&#xff0c;從而確保只讀訪問 1、返回內部引用對象 下面代碼中getData函數返…

PyTorch 學習筆記

環境&#xff1a;python3.8 PyTorch2.4.1cpu PyCharm 參考鏈接&#xff1a; 快速入門 — PyTorch 教程 2.6.0cu124 文檔 PyTorch 文檔 — PyTorch 2.4 文檔 快速入門 導入庫 import torch from torch import nn from torch.utils.data import DataLoader from torchvision …

windows開啟wsl與輕量級虛擬機管理

基于win 10 打造K8S應用開發環境&#xff08;wsl & kind&#xff09; 一、wsl子系統安裝 1.1 確認windows系統版本 cmd/powershell 或者win r 運行winver 操作系統要> 19044 1.2 開啟wsl功能 控制面板 -> 程序 -> 啟用或關閉Windows功能 開啟適用于Linux的…

C++ -異常之除以 0 問題(整數除以 0 編譯時檢測、整數除以 0 運行時檢測、浮點數除以 0 編譯時檢測、浮點數除以 0 運行時檢測)

一、整數除以 0&#xff08;編譯時檢測&#xff09; 1、演示 #include <iostream>using namespace std;int main() {int result 10 / 0;cout << result << endl;return 0; }程序無法運行&#xff0c;輸出結果 error C2124: 被零除或對零求模2、演示解讀 …

【藍橋杯】搜索算法:剪枝技巧+記憶化搜索

1. 可行性剪枝應用 1.1. 題目 題目描述: 給定一個正整數n和一個正整數目標值target,以及一個由不同正整數組成的數組nums。要求從nums中選出若干個數,每個數可以被選多次,使得這些數的和恰好等于target。問有多少種不同的組合方式? 輸入: 第一行:n和target,表示數組…

Uniapp 集成極光推送(JPush)完整指南

文章目錄 前言一、準備工作1. 注冊極光開發者賬號2. 創建應用3. Uniapp項目準備 二、集成極光推送插件方法一&#xff1a;使用UniPush&#xff08;推薦&#xff09;方法二&#xff1a;手動集成極光推送SDK 三、配置原生平臺參數四、核心功能實現1. 獲取RegistrationID2. 設置別…

Linux中進程

一、認識進程 進程(PCB)內核數據結構(task_struct)程序的代碼和數據 每一個進程都有其獨立的task_struct,OS對眾多的task_struct進行管理&#xff0c;如何管理&#xff1f;先描述再組織&#xff0c;所有運?在系統?的進程都以task_struct鏈表的形式存在內核?&#xff0c;而…

國外的AI工具

一 OpenAI &#xff1a; &#x1f4a1; 總覽&#xff1a; 名稱全稱/代號簡介GPT-4o“o” omniOpenAI 最新的旗艦多模態模型&#xff08;文字、圖像、音頻三模態&#xff09;&#xff0c;比 GPT-4 更強、更快、更便宜。GPT-4o-mini精簡版 GPT-4o輕量級版本&#xff0c;推測為性…

企業級Java開發工具MyEclipse v2025.1——支持AI編碼輔助

MyEclipse一次性提供了巨量的Eclipse插件庫&#xff0c;無需學習任何新的開發語言和工具&#xff0c;便可在一體化的IDE下進行Java EE、Web和PhoneGap移動應用的開發&#xff1b;強大的智能代碼補齊功能&#xff0c;讓企業開發化繁為簡。 立即獲取MyEclipse v2025.1正式版 具…

按鍵長按代碼

這些代碼都存放在定時器中斷中。中斷為100ms中斷一次。 數據判斷&#xff0c;看的懂就看吧

在 macOS 上連接 PostgreSQL 數據庫(pgAdmin、DBeaver)

在 macOS 上連接 PostgreSQL 數據庫 pgAdmin 官方提供的圖形化管理工具&#xff0c;支持 macOS。 下載地址&#xff1a;https://www.pgadmin.org/ pgAdmin 4 是對 pgAdmin 的完全重寫&#xff0c;使用 Python、ReactJs 和 Javascript 構建。一個用 Electron 編寫的桌面運行時…

FTP協議和win server2022安裝ftp

FTP協議簡介 FTP&#xff08;File Transfer Protocol&#xff0c;文件傳輸協議&#xff09;是一種用于在網絡上的計算機之間傳輸文件的標準網絡協議。它被廣泛應用于服務器與客戶端之間的文件上傳、下載以及管理操作。FTP支持多種文件類型和結構&#xff0c;并提供了相對簡單的…

人工智能——AdaBoost算法

目錄 摘要 13 AdaBoost算法 13.1 本章工作任務 13.2 本章技能目標 13.3 本章簡介 13.4 編程實戰 13.5 本章總結 13.6 本章作業 本章已完結! 摘要 本章實現的工作是:首先采用Python語言讀取數據并構造訓練集和測試集。然后建立AdaBoost模型,利用訓練集訓練該模型,…