27、Java 反射机制

news2025/3/4 16:05:44

15-1 Java 反射机制概述


Reflection(反射)是被视为动态语言的关键

动态语言:在运行时代码可以根据某些条件改变自身结构。如 C#\JavaScript\PHP

静态语言:运行时结构不可变的语言。如 Java\C\C++

问题:通过直接new的方式或反射的方式都可以调用公共的结构,开发中到底用哪个

建议:直接new的方式

反射特征:动态性


15-2 理解Class类并获取Class的实例


哪些类可以有Class对象?

1、class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类

2、interface:接口

3、[]:数组

4、enum:枚举

5、annotation:注解@interface

6、primitive type:基本数据类型

7、void


15-3类的加载与ClassLoader的理解

(主要了解即可)

CleanShot 2025-03-03 at 14.04.18


15-4 创建运行时类的对象

package com.java5.kcw;

import org.junit.Test;

/**通过反射创建对应的运行时类的对象
 * @author Jackson_kcw
 * @Time 2025-03-03  PM2:23
 */
public class NewInstanceTest {
    @Test
    public void test() throws InstantiationException, IllegalAccessException {
        Class clazz=Person.class;

        //newInstance():调用此方法,创建对应的运行时类的对象;内部调用了运行时类的空参构造器
        /*
        要想此方法正常的创建运行时类的对象,要求:
        1、运行时类必须提供空参的构造器
        2、空参的构造器的访问权限得够。通常,设置为 public

        在 javabean 中要求去提供一个 public 的空参构造器 原因:
        1、便于通过反射,创建运行时类的对象
        2、便于子类继承此运行时类,默认调用 super()时,保证父类有构造器
         */
        Object ob = clazz.newInstance();
        System.out.println(ob);
    }
}

体会反射的动态性,这是一个很重要的思想


15-5 调用运行时类的指定结构


package com.java5.kcw;

import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author Jackson_kcw
 * @Time 2025-03-03  PM2:51
 */
public class ReflectionTest1 {
    //这个方法现在已经很多不使用了,无需掌握
    @Test
    public void test1() throws Exception {
        Class clazz=Person.class;
        //创建运行时类的对象
        Person p=(Person)clazz.newInstance();

        //获取指定的属性:要求运行时类中属性声明为 public
        //通常不采用此方法
        Field id= clazz.getField("id");

        /*
        设置当前属性的值
        set():参数一:指明设置那个对象的属性    参数二:将此属性值设置为多少
         */
        id.set(p,1001);

        /*
        获取当前属性的值
        get() 参数一:获取哪个对象的当前属性值
         */
        int pId=(int)id.get(p);
        System.out.println(pId);


    }

    /*
    这个方法很重要的
     */
    @Test
    public void test2() throws Exception {
        Class clazz=Person.class;
        //创建运行时类的对象
        Person p=(Person)clazz.newInstance();

        //getDeclaredField(String fieldName):获取运行时类中指定变量名的属性
        Field name=clazz.getDeclaredField("name");

        //setAccessible(true) :保证当前属性是可访问的
        name.setAccessible(true);
        name.set(p,"Jackson");

        System.out.println(name.get(p));
    }

    //如何操作运行类中的指定方法
    @Test
    public void test3() throws Exception {
        Class clazz=Person.class;
        //创建运行时类的对象
        Person p=(Person)clazz.newInstance();

        Method setName = clazz.getDeclaredMethod("setName", String.class);
        setName.setAccessible(true);
        //invoke() 参数 1:方法的调用者  参数二:给方法形参赋值的实参
        //invoke()返回值即为对应类中调用的方法的返回值
        setName.invoke(p,"Kik");
        System.out.println(p.getName());
        System.out.println("****************如何调用静态方法*****************");


        Method showDesc = clazz.getDeclaredMethod("showDesc");
        showDesc.setAccessible(true);
        showDesc.invoke(p);
    }
}


15-6 反射的应用:动态代理


package com.java6.kcw;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**动态代理
 * @author Jackson_kcw
 * @Time 2025-03-03  PM3:25
 */

interface Human{
    String getBelief();

    void eat(String food);

}
//被代理类
class SuperMan implements Human{


    @Override
    public String getBelief() {
        return "I believe I can Fly";
    }

    @Override
    public void eat(String food) {
        System.out.println("I like eat"+food);
    }
}
/*
想要实现动态代理,需要解决的问题?
问题一:如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象
问题二:当通过代理类的对象调用方法时,如何动态的去调用被代理类中的同名方法

 */

class ProxyFactory{
    //调用此方法,返回一个代理类的对象,解决问题一
    public static Object getProxyInstance(Object obj){//obj:被代理类的对象
        MyInvocationHandler handle= new MyInvocationHandler();
        handle.bind(obj);

       return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),handle);

    }
}
class MyInvocationHandler implements InvocationHandler {
    private Object obj;//需要使用被代理类的对象进行赋值
    public void bind(Object obj){
        this.obj = obj;
    }

    //当我们通过代理类的对象,调用方法 a 时,就会自动的调用如下的方法:invoke()
    //将被代理类要执行的方法 a 的功能就声明在 invoke()中
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //method:即为代理类对象调用的方法,此方法也就作为 被代理类对象要调用的方法
        //obj:被代理类的对象
        Object returnValue = method.invoke(obj, args);
        //上述方法的返回值就作为当前类中的 invoke()的返回值
        return returnValue;
    }
}
public class ProxyTest {
    public static void main(String[] args) {
        SuperMan superman = new SuperMan();
        //proxyInstance:代理类的对象
        Human human = (Human) ProxyFactory.getProxyInstance(superman);
        //当通过代理类对象调用方法时,会自动调用被代理类中同名的方法
        human.getBelief();
        human.eat("烧烤");

    }
}



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

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

相关文章

Android 端侧运行 LLM 框架 MNN 及其应用

MNN Chat Android App - 基于 MNN 引擎的智能聊天应用 一、MNN 框架简介与工作原理1.1 什么是 MNN?1.2 MNN 的工作原理 二、MNN Chat Android App2.1 MNN Chat 的功能2.2 MNN Chat 的优势2.3 MNN Chat Android App 的使用 三、总结 随着移动端人工智能需求的日益增长…

FPGA学习(一) —— 四位全加器

FPGA学习(一) —— 四位全加器 文章目录 FPGA学习(一) —— 四位全加器一、半加器1、半加器的真值表2、Verilog代码实现3、RTL原理图4、波形仿真 二、一位全加器1、一位全加器真值表2、Verilog代码实现3、RTL原理图4、波形仿真 三…

PHP:IDEA开发工具配置XDebug,断点调试

文章目录 一、php.ini配置二、IDEA配置 一、php.ini配置 [xdebug] zend_extension"F:\wamp64\bin\php\php7.4.0\ext\php_xdebug-2.8.0-7.4-vc15-x86_64.dll" xdebug.remote_enable on xdebug.remote_host 127.0.0.1 xdebug.remote_port 9001 xdebug.idekey"…

LINUX网络基础 - 网络编程套接字,UDP与TCP

目录 前言 一. 端口号的认识 1.1 端口号的作用 二. 初识TCP协议和UDP协议 2.1 TCP协议 TCP的特点 使用场景 2.2 UDP协议 UDP的特点 使用场景 2.3 TCP与UDP的对比 2.4 思考 2.5 总结 三. 网络字节序 3.1 网络字节序的介绍 3.2 网络字节序思考 四. socket接口 …

QT实现单个控制点在曲线上的贝塞尔曲线

最终效果: 一共三个文件 main.cpp #include <QApplication> #include "SplineBoard.h" int main(int argc,char** argv) {QApplication a(argc, argv);SplineBoard b;b.setWindowTitle("标准的贝塞尔曲线");b.show();SplineBoard b2(0.0001);b2.sh…

Linux基础开发工具(vim编译器,yum与apt软件安装)

Linux 下载安装软件的方案 源代码安装-》》》非常麻烦与复杂一步错步步错 rmp包安装 -》》》只是安装没有对应的库与依赖相当于只是一个外壳 包管理器进行安装-》》 yum / apt(本篇重点讲解) 1.什么是软件包和软件包管理器 就好⽐ "App" 和 "应⽤商店"…

神经网络 - 激活函数(Maxout 单元)

一、Maxout 单元 Maxout 单元是一种特殊的激活函数&#xff0c;用于神经网络中&#xff0c;其主要思想是通过多个线性变换的最大值来作为神经元的输出&#xff0c;从而提高模型的表达能力和鲁棒性。 1. 数学定义 假设输入为 x&#xff0c;Maxout 单元会计算 k 个线性变换&am…

nginx+keepalived负载均衡及高可用

1 项目背景 keepalived除了能够管理LVS软件外&#xff0c;还可以作为其他服务的高可用解决方案软件。采用nginxkeepalived&#xff0c;它是一个高性能的服务器高可用或者热备解决方案&#xff0c;Keepalived主要来防止服务器单点故障的发生问题&#xff0c;可以通过其与Nginx的…

VirtualBox虚拟机转VM虚拟机

前言&#xff1a;部分靶机只适用于VirtualBox&#xff0c;VM打不开VirtualBox的文件&#xff0c;所以需要进行转换 前置条件&#xff1a;本机已经下载VM和VirtualBox 第一步&#xff1a;文件转换 找到VirtualBox.exe所在位置&#xff0c;启动cmd窗口 文件转换的命令&#xf…

使用DeepSeek+KIMI生成高质量PPT

一、使用DeepSeek DeepSeek官网&#xff1a;DeepSeek 点击“开始对话”&#xff0c;进入交互页面。 在上图中&#xff0c;输入问题&#xff0c;即可获取AI生成的结果。 基础模型&#xff08;V3&#xff09;&#xff1a;通用模型&#xff08;2024.12&#xff09;&#xff0c;高…

基于SpringBoot的失物招领平台的设计与实现

基于SpringBoot的失物招领平台的设计与实现 基于微信小程序的失物招领系统 失物招领小程序 校园失物招领小程序 基于微信小程序SSMMySQL开发&#xff0c;高分JAVA成品毕业设计&#xff0c;附带往届论文、启动教程、讲解视频、二次开发教程和配套安装包文件&#xff0c;论文中…

鸿蒙NEXT开发-元服务和服务卡片的开发

注意&#xff1a;博主有个鸿蒙专栏&#xff0c;里面从上到下有关于鸿蒙next的教学文档&#xff0c;大家感兴趣可以学习下 如果大家觉得博主文章写的好的话&#xff0c;可以点下关注&#xff0c;博主会一直更新鸿蒙next相关知识 目录 1. 元服务基本概念 1.1 基本介绍 1.2 元…

【Spark+Hive】基于Spark大数据技术小红书舆情分析可视化预测系统(完整系统源码+数据库+开发笔记+详细部署教程+虚拟机分布式启动教程)✅

目录 一、项目背景 二、项目目标 三、算法介绍 四、开发技术介绍 五、项目创新点 六、项目展示 七、权威教学视频 源码获取方式在文章末尾 一、项目背景 在数字经济蓬勃发展的当下&#xff0c;社交电商平台小红书凭借其"内容电商"的独特模式&#xff0c;已…

IO基础知识和练习

一、思维导图 二、练习 1.使用标准IO函数&#xff0c;实现文件的拷贝 #include <head.h> int main(int argc, const char *argv[]) {FILE *pfopen("./one.txt","r");FILE *fpfopen("./two.txt","r");if(pNULL)PRINT_ERROR(&qu…

gradle libs.versions.toml文件

1.libs.versions.toml介绍2.创建libs.versions.toml文件3.libraries5.versions6.plugins7.bundles 1.libs.versions.toml介绍 下图是官网介绍 意思就是说项目所有插件和库的依赖版本都统一在这个文件配置。 文件中有以下四个部分 versions, 申明要使用的插件和库的版本号的…

2025 Lakehouse 趋势全景展望:从技术演进到商业重构

1. 为什么湖仓正在成为企业数据架构的必选项&#xff1f; 越来越多的企业正在通过实时数据处理能力构建核心竞争力——用户期待 APP 精准捕捉需求并实时响应&#xff0c;企业员工追求业务系统的秒级反馈&#xff0c;这些场景背后是千亿级数据资产的敏捷调度。 据 IDC 预测&am…

一、NRF2401无线通信模块使用记录

一、电路引脚图 1、引脚说明&#xff1a; 2、引脚标号&#xff1a; 找到1号引脚&#xff0c;与原理图对号入座。 3、cubemx初始化配置&#xff1a; 5、驱动文件 配置spi&#xff0c;并构建发送与接收函数接口 .h #define TX_ADR_WIDTH 5 //发射地址宽度 #define TX_PLO…

NVIDIA GPU 架构详解:Pascal、Volta、Turing、Ampere、Ada、Hopper、Blackwell

目录 1. Pascal&#xff08;帕斯卡&#xff09;架构&#xff08;2016&#xff09;关键技术性能特性代表产品应用场景 2. Volta&#xff08;伏特&#xff09;架构&#xff08;2017&#xff09;关键技术性能特性代表产品应用场景 3.Turing&#xff08;图灵&#xff09;架构&#…

初阶数据结构(C语言实现)——3顺序表和链表(2)

2.3 数组相关面试题 原地移除数组中所有的元素val&#xff0c;要求时间复杂度为O(N)&#xff0c;空间复杂度为O(1)。OJ链接 力扣OJ链接-移除元素删除排序数组中的重复项。力扣OJ链接-删除有序数组中的重复项合并两个有序数组。力扣OJ链接-合并两个有序数组 2.3.1 移除元素 1…

IP-----BGP协议

7.BGP协议 1.BGP的所属分类 2.BGP的特性 3.BGP的数据包 4.BGP的6种状态机 5.BGP的工作过程 6.BGP的路由黑洞 1.BGP路由黑洞 2.解决方法 7.BGP的防环 1.EBGP水平分割 2.IBGP水平分割 1.解决IBGP环路的规则 2.解决IBGP水平分割问题 3.作用 8.BGP的基础配置 1.查看…