Java进阶-day06:反射、注解与动态代理深度解析

news2025/4/6 7:24:26

目录

一、反射机制:Java的自我认知能力

1.1 认识反射

1.2 获取Class对象

1.3 获取类的成分

二、注解:Java的元数据机制

2.1 注解概述

2.2 元注解

2.3 注解解析

2.4 注解的实际应用

三、动态代理:灵活的间接访问机制

3.1 为什么需要代理

3.2 Java动态代理实现

3.3 动态代理的实际应用

四、总结


一、反射机制:Java的自我认知能力

1.1 认识反射

反射(Reflection)是Java语言的一种强大特性,它允许程序在运行时获取类的内部信息,并能直接操作类或对象的内部属性和方法。这种"自我认知"能力打破了传统编程的静态模式,为Java带来了极大的灵活性。

反射的核心思想是:在运行时而非编译时确定和操作类的信息。这使得我们可以编写出更加通用和灵活的代码,但也带来了性能开销和安全考虑。

1.2 获取Class对象

要使用反射,首先需要获取类的Class对象,Java提供了三种方式:

// 1. 通过类名.class获取
Class<String> stringClass = String.class;

// 2. 通过对象.getClass()获取
String str = "Hello";
Class<?> strClass = str.getClass();

// 3. 通过Class.forName()动态加载
Class<?> arrayListClass = Class.forName("java.util.ArrayList");

1.3 获取类的成分

获取Class对象后,我们可以深入探索类的各个组成部分:

获取构造方法:

Constructor<?>[] constructors = String.class.getConstructors();
Constructor<?> stringConstructor = String.class.getConstructor(String.class);

获取字段信息:

Field[] fields = MyClass.class.getDeclaredFields();
Field nameField = MyClass.class.getDeclaredField("name");
nameField.setAccessible(true); // 突破私有访问限制

获取方法信息:

Method[] methods = MyClass.class.getDeclaredMethods();
Method method = MyClass.class.getMethod("setName", String.class);
Object result = method.invoke(obj, "newName"); // 调用方法

反射在实际开发中应用广泛,如:

  • IDE的代码提示功能

  • Spring框架的依赖注入

  • JUnit测试框架

  • 序列化/反序列化工具

二、注解:Java的元数据机制

2.1 注解概述

注解(Annotation)是Java 5引入的一种元数据机制,它提供了一种向代码添加信息的方式,这些信息可以被编译器、运行时环境或其他工具读取和处理。

注解的本质是接口,它通过@interface关键字定义:

public @interface MyAnnotation {
    String value() default "";
    int priority() default 0;
}

2.2 元注解

元注解是用来注解其他注解的注解,Java提供了以下几种:

  1. @Target:指定注解可以应用的目标(类、方法、字段等)

  2. @Retention:指定注解的保留策略(源码、class文件、运行时)

  3. @Documented:指示注解应该被包含在JavaDoc中

  4. @Inherited:指示子类可以继承父类的注解

  5. @Repeatable(Java 8+):允许在同一位置重复使用同一注解

2.3 注解解析

定义注解后,我们需要通过反射机制来解析和使用它们:

// 获取类上的注解
MyAnnotation classAnnotation = MyClass.class.getAnnotation(MyAnnotation.class);

// 获取方法上的注解
Method method = MyClass.class.getMethod("someMethod");
MyAnnotation methodAnnotation = method.getAnnotation(MyAnnotation.class);

// 处理注解信息
if (methodAnnotation != null) {
    System.out.println("Value: " + methodAnnotation.value());
    System.out.println("Priority: " + methodAnnotation.priority());
}

2.4 注解的实际应用

注解在现代Java开发中无处不在:

  1. 框架配置:Spring的@Controller@Service

  2. 测试:JUnit的@Test@Before

  3. 持久化:JPA的@Entity@Column

  4. 代码生成:Lombok的@Getter@Setter

  5. 验证:Bean Validation的@NotNull@Size

三、动态代理:灵活的间接访问机制

3.1 为什么需要代理

代理模式的核心思想是通过一个代理对象来控制对真实对象的访问。在以下场景中代理特别有用:

  1. 访问控制:限制对真实对象的直接访问

  2. 功能增强:在不修改原始对象的情况下添加额外功能

  3. 延迟加载:当创建对象开销很大时,推迟实际创建时间

  4. 日志记录:自动记录方法调用信息

  5. 事务管理:自动为方法调用添加事务支持

3.2 Java动态代理实现

Java提供了java.lang.reflect.Proxy类来创建动态代理:

// 1. 定义接口
public interface UserService {
    void addUser(String username);
    void deleteUser(String username);
}

// 2. 实现接口
public class UserServiceImpl implements UserService {
    public void addUser(String username) {
        System.out.println("添加用户: " + username);
    }
    
    public void deleteUser(String username) {
        System.out.println("删除用户: " + username);
    }
}

// 3. 实现InvocationHandler
public class UserServiceProxy implements InvocationHandler {
    private Object target;
    
    public UserServiceProxy(Object target) {
        this.target = target;
    }
    
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("准备执行: " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("执行完成: " + method.getName());
        return result;
    }
}

// 4. 使用代理
public class Main {
    public static void main(String[] args) {
        UserService realService = new UserServiceImpl();
        UserService proxy = (UserService) Proxy.newProxyInstance(
            UserService.class.getClassLoader(),
            new Class[]{UserService.class},
            new UserServiceProxy(realService)
        );
        
        proxy.addUser("张三");
        proxy.deleteUser("李四");
    }
}

3.3 动态代理的实际应用

  1. Spring AOP:基于动态代理实现面向切面编程

  2. RPC框架:远程方法调用的本地代理实现

  3. MyBatis:Mapper接口的代理实现

  4. Hibernate:延迟加载的代理实现

  5. 日志系统:自动化的方法调用日志记录

四、总结

反射、注解和动态代理是Java高级编程中的三大核心技术,它们共同构成了Java灵活性和扩展性的基础:

  1. 反射:赋予Java程序在运行时自省和操作类结构的能力

  2. 注解:为Java代码提供强大的元数据支持

  3. 动态代理:实现了灵活的间接访问和功能增强机制

这些技术虽然强大,但也应谨慎使用:

  • 反射会带来性能开销和安全风险

  • 过度使用注解可能导致代码可读性下降

  • 动态代理可能掩盖真实的调用流程

理解并合理运用这些高级特性,能够帮助我们构建更加灵活、可扩展的Java应用程序,也是深入理解主流Java框架的基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2329054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis数据结构之Hash

目录 1.概述2.常见操作2.1 H(M)SET/H(M)GET2.2 HGETALL2.3 HDEL2.4 HLEN2.5 HEXISTS2.6 HKEYS/HVALS2.7 HINCRBY2.8 HSETNX 3.总结 1.概述 Hash是一个String类型的field(字段)和value(值)的映射表&#xff0c;而且value是一个键值对集合&#xff0c;类似Map<String, Map<…

故障矩阵像素照片效果ps标题文本特效滤镜样机 Glitched Arcade Text Logo Effect

有时&#xff0c;视觉效果比文字本身更能讲述故事&#xff0c;因此请确保您已竭尽全力提供令人敬畏的展示。品牌标识或演示元素&#xff0c;该资产可以处理您的项目所涉及的任何内容。由于智能对象图层&#xff0c;此文本效果将为获得理想的结果铺平道路。这些允许您在指定的图…

[创业之路-352]:从创业和公司经营的角度看:分析美国的三大财务报表

一、美国政府的财务报表 如果把美国政府看成一个公司&#xff0c;从三大财务报表上看&#xff0c;美国政府资产雄厚&#xff0c;但利润表年年亏损&#xff0c;现金流量表年年为负&#xff0c;现金流持续吃紧&#xff0c;面临现金流断裂导致公司倒闭的风险。 马斯克在降低公司各…

【教学类-102-02】自制剪纸图案(留白边、沿线剪)02——Python+PS自动化添加虚线边框

背景需求: 01版本实现了对透明背景png图案边界线的扩展,黑线实线描边 【教学类-102-01】自制剪纸图案(留白边、沿线剪)01-CSDN博客文章浏览阅读974次,点赞15次,收藏7次。【教学类-102-01】自制剪纸图案(留白边、沿线剪)01https://blog.csdn.net/reasonsummer/article…

OFP--2018

文章目录 AbstractIntroductionRelated Work2D object detection3D object detection from LiDAR3D object detection from imagesIntegral images 3D Object Detection ArchitectureFeature extractionOrthographic feature transformFast average pooling with integral imag…

CentOS-查询实时报错日志-查询前1天业务报错gz压缩日志

最新版本更新 https://code.jiangjiesheng.cn/article/364?fromcsdn 推荐 《高并发 & 微服务 & 性能调优实战案例100讲 源码下载》 1. 查询实时报错日志 物理路径&#xff08;带*的放在靠后&#xff0c;或者不用*&#xff09; cd /home/logs/java-gz-log-dir &am…

ETF 场内基金是什么?佣金最低又是多少呢?

嘿&#xff0c;朋友们&#xff0c;大家好啊&#xff0c;我是StockMasterX&#xff0c;今天咱们就坐下来慢慢聊聊这个话题&#xff0c;ETF 场内基金到底是个啥东西&#xff0c;它的佣金最低能到多少&#xff0c;真的是个值得深挖的问题。 说起ETF&#xff0c;我还记得刚入行那会…

[论文阅读]PMC-LLaMA: Towards Building Open-source Language Models for Medicine

PMC-LLaMA&#xff1a;构建医学开源语言模型 摘要 最近&#xff0c;大语言模型在自然语言理解方面展现了非凡的能力。尽管在日常交流和问答场景下表现很好&#xff0c;但是由于缺乏特定领域的知识&#xff0c;这些模型在需要精确度的领域经常表现不佳&#xff0c;例如医学应用…

26考研——线性表(2)

408答疑 文章目录 一、线性表的定义和基本操作二、线性表的顺序表示三、 线性表的链式表示四、 顺序表和链表的比较五、参考资料鲍鱼科技课件26王道考研书 六、总结顺序表总结顺序表特点深入掌握顺序表的管理方式 单链表总结双循环链表总结 一、线性表的定义和基本操作 文章链…

低代码开发平台:飞帆画 echarts 柱状图

https://fvi.cn/711 柱状图这个控件是由折线图的控件改过来的&#xff0c;在配置中&#xff0c;单选框选择柱状图就行了。

PowerPhotos:拯救你的Mac照片库,告别苹果原生应用的局限

如果你用Mac管理照片&#xff0c;大概率被苹果原生「照片」应用折磨过——无法真正并行操作多个图库。每次切换图库都要关闭重启&#xff0c;想合并照片得手动导出导入&#xff0c;重复文件更是无处可逃…… 直到我发现了 PowerPhotos&#xff0c;这款专为Mac设计的照片库管理…

Linux 下 日志系统搭建全攻略

目录 一、引言 二、日志系统基础 日志级别 日志输出格式 三、创建日志所需函数 认识可变参数 ​编辑 获取时间的函数 小结 四、创建日志 一、引言 在 Linux 环境中开发 C/C 程序时&#xff0c;日志系统是不可或缺的一部分。它不仅有助于调试程序、排查问题&#xff…

Linux系统安装Postgre和Postgis教程

卸载 如果之前没装过可以忽略这一步 卸载前记得备份数据库数据(如果还需要的话)&#xff01;&#xff01;&#xff01; 一、删除 Docker 安装的 PostgreSQL/PostGIS 1. 停止并删除容器 # 查看所有容器 docker ps -a | grep postgres# 停止并删除容器&#xff08;替换为实际…

LXC 导入多Linux系统

前提要求 ubuntu下安装lxd 参考Rockylinux下安装lxd 参考LXC 源替换参考LXC 容器端口发布参考LXC webui 管理<

6547网:蓝桥STEMA考试 Scratch 试卷(2025年3月)

『STEMA考试是蓝桥青少教育理念的一部分&#xff0c;旨在培养学生的知识广度和独立思考能力。考试内容主要考察学生的未来STEM素养、计算思维能力和创意编程实践能力。』 一、选择题 第一题 运行下列哪个程序后&#xff0c;飞机会向左移动&#xff1f; ( ) A. …

使用Webpack搭建React项目:从零开始

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…

STM32提高篇: CAN通讯

STM32提高篇: CAN通讯 一.CAN通讯介绍1.物理层2.协议层二.STM32CAN外设1.CAN控制器的3种工作模式2.CAN控制器的3种测试模式3.功能框图三.CAN的寄存器介绍1.环回静默模式测试2.双击互发测试四.CAN的HAL代码解读一.CAN通讯介绍 CAN(Controller Area Network 控制器局域网,简称…

25.Reactor

预备知识 std::bind template <class Fn, class... Args>/* unspecified */ bind (Fn&& fn, Args&&... args);解释&#xff1a; std::bind(&TcpServer::Accepter, this, std::placeholders::_1) 这段代码使用了 C11 中的 std::bind 函数&#xff0…

Linux进程间通信——有名管道

一.概念 函数形式&#xff1a;int mkfifo(const char \*filename,mode_t mode); 功能&#xff1a;创建管道文件 参数&#xff1a;管道文件文件名\路径&#xff0c;权限&#xff0c;创建的文件权限仍然和umask有关系。 返回值&#xff1a;创建成功返回0&#xff0c;创建失败返回…

Axure RP9.0教程: 查询条件隐藏与显示(综合了动态面板状态切换及展开收缩效果实现)

文章目录 引言I 原型显示/隐藏搜索框思路步骤详细操作II 若依 ruoyi 显示/隐藏搜索框 & 显示隐藏列自定义设置显示隐藏列显示/隐藏搜索框引言 数据筛选有大量的查询条件时,可以选择查询隐藏效果。 I 原型显示/隐藏搜索框 综合了动态面板状态切换及展开收缩效果实现 思…