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.mzph.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模型,利用训练集训练该模型,…