反射及其应用---->2
目录
1.使用类对象
1.1创建对象
1.2使用对象属性
1.3使用方法
2.反射操作数组
3.反射获得泛型
4.类加载器
4.1双亲委派机制
4.2自定义加载器
1.使用类对象
-
通过反射使用类对象,主要体现3个部分
-
创建对象,调用方法,调用属性(存值,取值)
1.1创建对象
利用反射创建对象有两种方式
-
通过构造器创建对象(推荐)
-
通过Class直接创建对象(只支持利用无参构造器创建对象)
Object o = c.newInstance(); //使用无参构造器创建对象Constructor con = c.getConstructor(int.class, int.class);
//A a = new A(10,20);
Object o = con.newInstance(10, 20);
1.2使用对象属性
-
包括使用属性赋值, 使用属性取值。
-
需要先获得要操作的属性对象
Object a1 = c.newInstance();Field n = c.getField("n"); //获得的public的属性n.set(a1,"XXXX");Object value = n.get(a1);
System.out.println(value);
//私有属性,可以通过设置i.setAccessible(true) 实现对私有成员的访问
//注意1: 使用后,建议将其重新锁住 i.setAccessible(false)
//注意2: 强烈不推荐使用该方式操作私有成员,建议通过封装,提供对应的get和set方法。
Field i = c.getDeclaredField("i");
i.setAccessible(true);
i.set(null,100); //传递null,是因为i属性是一个static属性
Object value = i.get(null);
System.out.println(value);
i.setAccessible(false);
-
在jdk1.9之后,对java中的类库做了重新的处理
-
增加了一个模块的功能,成员属于类,类属于包,包属于模块, 模块属于程序
-
包中的类需要export导出,其他模块中的类才可见。
-
包中未导出的类,其他模块中的类不可见,不可引入,不可反射操作
-
当然,可以通过jvm参数配置,使得模块中的内容都可以反射操作。
-
1.3使用方法
反射调用对象的方法,需要先获得对应的Method方法对象
-
获得Method对象时,除了指定方法名,还需要指定方法的参数列表(Class)
-
调用方法时,需要指定所属对象(static方法所属null或Class),需要传递具体的参数值(Object)
Object a = c.newInstance();
Method m = c.getMethod("t1", int.class, int.class);//t1(int,int)
//a.t1(100,200);
Object r = m.invoke(a, 100, 200);
Method m = c.getDeclaredMethod("t2");//t2()
m.setAccessible(true);
m.invoke(a) ;
m.setAccessible(false);
2.反射操作数组
反射操作数组,使用的是Array类
//Object array = new int[5];
//array[1] (取值, 赋值)
Object array = Array.newInstance(int.class, 5);Array.set( array , 0 , 250 );Object value = Array.get(array, 0);
System.out.println(value);int len = Array.getLength(array);
System.out.println(len);
3.反射获得泛型
关于反射获得泛型,有两种操作需求
-
获得类定义时的泛型 T , V , K , E
public static void t1(){Class c = A.class;TypeVariable[] typeParameters = c.getTypeParameters();//类定义时的泛型System.out.println(typeParameters.length);System.out.println(typeParameters[0].getName());
}
2.获得类使用时的泛型,具体的类型 List<String>
public static void t2() throws NoSuchFieldException, NoSuchMethodException {Class c = B.class ;Field a = c.getDeclaredField("a");Type type = a.getGenericType();//一般getGeneric系列,都是用来获得所包含的泛型的。//(属性类型,返回类型,参数类型,父类型,父接口类型)都有该系列方法//Class is a Type //泛型类型,也称为参数化类型 is a Type , 本质是 ParameterizedTypeParameterizedType pt = (ParameterizedType) type;//Type[] pts = pt.getActualTypeArguments(); //获得多个泛型的数组Type rawType = pt.getRawType();//获得泛型类型}
4.类加载器
-
JVM在运行程序时,会使用类加载器,加载(读取)类文件的信息,并对其进行一系列的处理,最终将其存储在方法区,并生成与之对应的Class对象。
-
类信息有不同的情况
-
有我们自己的写的类信息
-
有jdk自带的类信息
-
未来可能还有其他的类信息,如:网络中的类信息,需要加密处理类信息等。
-
-
jdk针对于不同的类信息情况,提供了不同的类加载器,默认有3种
-
BootstrapClassLoader 启动类加载器,使用C/C++实现,加载jdk基本类库,如:java.lang等
-
ExtClassLoader 扩展类加载器,使用Java实现的,加载jdk扩展类库
-
AppClassLoader 应用类加载器,使用Java实现的,classpath路径中的类,我们自己编写的类
-
4.1双亲委派机制
-
jdk提供了3个加载器,未来我们还能自定义加载器
-
jdk同时提供了双亲委派机制,使得多个加载器可以更合理的协作应用
-
当我们在程序中需要使用一个类时,会先向最底层的类加载器申请这个类(app)
-
如果app加载器加载过这个类,就会返回该类的Class对象
-
如果app没有加载过这个类,app会向其父级加载器(ext)申请这个类
-
如果ext加载过就返回这个类,如果没有加载过这个类,继续想起父级(Bootstrap)申请
-
如果bootstrap加载过就返回这个类,如果没有加载过,就尝试加载
-
如果在bootstrap的加载范围内,则加载这个类
-
如果不再bootstrap的加载范围内, 尝试让ext加载
-
如果在ext加载范围内,就让ext加载。如果不在就尝试让app加载
-
如果在app加载范围内,就让app加载,否则就抛出ClassNotFoundException
-
-
注意:app 和 ext 和 bootstrap是逻辑上的子父级关系,不是真正 的extends继承关系
-
双亲委派机制的优点
-
防止核心类被篡改。
-
方式类重复加载
-
防止在核心包中扩展类(沙箱机制)
-
4.2自定义加载器
-
哪些情况需要自定义类加载器呢?
-
扩展加载源 ,如:从网络中加载类库
-
类的隔离
-
类信息的解密
-
-
如何自定义类加载器
-
自定义加载器类, 继承ClassLoader
-
重写方法
-
可以重写
loadClass方法,但不推荐。因为该方法中提供了双亲委派机制如果重写该方法,相等于破坏了双亲委派机制。
-
可以重写
findClass方法,根据需求,去指定的地方获取类文件信息以byte[]的形式装载找到的类信息
-
还有一个很重要的方法
defineClass(),用来将字节码内容进行一系列的处理,并存储在方法区,并生成Class对象所以在findClass之后,一定要调用该方法。
-
-
使用类加载器
-
public class MyClassLoader extends ClassLoader{//name 一般就是com.buka.User 类路径//可以根据这个类路径确定最重要加载的目标类@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {try {Socket link = new Socket("localhost",6666);InputStream is = link.getInputStream();//存储所有读取到的字节信息//本来是需要使用字节数组//但无法确定从网络中读取字节的数量,就不知道要定义多长的字节数组//可以使用ByteArrayOutputStreamByteArrayOutputStream bos = new ByteArrayOutputStream();byte[] bs =new byte[010];while(true){int len = is.read(bs);if(len == -1){break ;}bos.write(bs,0,len);}byte[] content = bos.toByteArray();return super.defineClass("X",content,0,content.length);} catch (IOException e) {throw new RuntimeException(e);}}
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {MyClassLoader loader = new MyClassLoader();Class<?> c = loader.loadClass("X");c.newInstance();
}
相关文章:
反射及其应用---->2
目录 1.使用类对象 1.1创建对象 1.2使用对象属性 1.3使用方法 2.反射操作数组 3.反射获得泛型 4.类加载器 4.1双亲委派机制 4.2自定义加载器 1.使用类对象 通过反射使用类对象,主要体现3个部分 创建对象,调用方法,调用属性ÿ…...
[Python学习日记-32] Python 中的函数的返回值与作用域
[Python学习日记-32] Python 中的函数的返回值与作用域 简介 返回值 作用域 简介 在函数的介绍中我们提到了函数的返回值,当时只是做了简单的介绍,下面我们将会进行详细的介绍和演示,同时也会讲一下 Python 中的作用域,作用域分…...
儿童发光耳勺值得买吗?儿童发光耳勺最建议买的五个牌子!
儿童耳部清洁需谨慎,发光耳勺能在光线不足时提供照明,便于看清耳道。但不同产品质量参差不齐,选择时需综合考虑安全性、实用性等因素,为孩子的耳部健康做出正确选择! 这里给大家总结了全新的儿童发光耳勺的避雷指南&am…...
TIPS 二进制程序暴露符号给动态链接库使用
背景 在支持插件/扩展的C/C系统中,通常会支持在程序运行时加载动态链接库。这时二进制程序会提供一些函数/接口让动态链接库调用,但是这些函数在二进制程序中又不会使用,导致在编译时编译器直接把这些符号删除了,加载链接库就会由…...
【分布式微服务云原生】8分钟掌握微服务通信的艺术:Dubbo与OpenFeign全面解析
摘要: 在构建微服务架构时,服务间的通信机制是核心要素之一。Dubbo和OpenFeign是两个非常流行的服务调用框架,它们各有千秋,适用于不同的场景。本文将深入探讨Dubbo和OpenFeign的主要特点、使用场景以及它们之间的差异,…...
sicp每日一题[2.33]
Exercise 2.33 Fill in the missing expressions to complete the following definitions of some basic list-manipulation operations as accumulations: ; p 表示一个函数,sequence 表示一个列表 ; 这个函数将对列表中每一个元素进行 p 操作 (define (map p sequ…...
【Mybatis】常见面试题汇总 共56题
文章目录 1. 介绍下MyBatis?2. MyBatis 框架的应用场景?3. MyBatis 有哪些优点?4. MyBatis 有哪些缺点?5. MyBatis 用到了哪些设计模式?6. MyBatis常用注解有哪些?7. MyBatis 有哪些核心组件?8. MyBatis编程步骤是什么样的?9. MyBatis 和…...
每天一道面试题(17):服务网格学习笔记
什么是服务网格? 服务网格(Service Mesh)是处理微服务间通信的一种基础设施层。它主要用于解耦服务间的通信与业务逻辑,使开发者可以专注于业务实现。服务网格在微服务架构的演进中扮演了重要角色,特别是在解决服务间…...
【nrm】npm 注册表管理器
nrm是什么 nrm(NPM Registry Manager)是一个用于管理 Node.js 包管理器(如 npm 和 Yarn)的注册表工具。它可以帮助用户快速切换不同的 npm 源,以便于提高包安装的速度和效率,特别是在中国大陆地区…...
解压短视频素材资源网站推荐
如果你正在寻找解压短视频素材,那么这篇文章正是为你而写!以下是一些热门的网站,帮助你轻松找到所需的素材,快来看看吧! 蛙学网 蛙学网是国内领先的视频素材网站,提供丰富的解压视频素材。无论是放松心情的…...
Qemu开发ARM篇-6、emmc/SD卡AB分区镜像制作并通过uboot进行挂载启动
文章目录 1、AB分区镜像制作2、uboot修改3、镜像启动 在上一篇 Qemu开发ARM篇-5、buildroot制作根文件系统并挂载启动中,我们通过buildroot制作了根文件系统,并通过 SD卡的形式将其挂载到设备并成功进行了启动,但上一章中,我们的…...
Spring Boot中使用ThreadPoolTaskScheduler实现轻量级多线程定时任务
引言 在Java开发中,Spring Boot提供了多种方式来执行定时任务,如Scheduled注解和TaskScheduler。当需要执行多线程定时任务时,ThreadPoolTaskScheduler是一个轻量级的解决方案。本文将通过一个具体的业务场景,介绍如何使用Thread…...
完全二叉树的节点个数 C++ 简单问题
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。 示例 1ÿ…...
每日一题学习笔记
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以,返回 true ;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1: 输入&#…...
从事人工智能学习Python还是学习C++?
人工智能(Artificial Intelligence,简称AI)是当今科技领域最热门的研究方向之一。AI 涉及多个学科和技术,特别是机器学习、神经网络、深度学习等技术的应用。在AI的开发过程中,编程语言的选择对于开发效率和项目实现至…...
博客摘录「 CNN中的感受野和有效感受野会对模型产生怎样的影响?」2024年9月29日
,中心像素受影响较大,离中心越远梯度信号越弱。梯度信号的衰减是指数级的,这意味着应用于感受野的大多数像素的梯度将是可忽略的(如果有的话)。 有效感受野的定义...
AURIX单片机示例:开发入门与点亮LED
文章目录 目的模板工程Blinky_LED示例链接总结 目的 这个例程比较简单,主要通过这个例程来介绍 AURIX™ Development Studio(ADS) 和 iLLD 库来开发 AURIX 系列单片机一些入门的内容。一些更为基础的资料等内容可以参考下面文章: 《英飞凌 AURIX TriCo…...
MySQL字符串函数与操作
在编程领域中,字符串操作是数据处理中至关重要的一部分。无论是文本分析、日志处理,还是格式化输出,字符串的操作技能都能极大提高工作效率。在 Python 中,字符串相关的函数和方法为开发者提供了强大的工具,帮助完成各种任务。了解如何灵活运用这些工具,能够有效提升编程…...
HTML+CSS 水滴登录页
文章目录 一、效果演示二、Code1.HTML2.CSS 三、实现思路拆分 一、效果演示 实现了一个水滴登录页的效果。页面包含一个水滴形状的登录框和两个按钮,登录框包括用户名、密码和登录按钮,按钮分别为忘记密码和注册。整个页面的设计非常有创意,采…...
基于Next.js和TailwindCss的TailwindCss
最近在研究 Next.js 和 TailwindCss ,这两天没事的时候就搞了一个 c。 目前工具部署在 Vercel ,欢迎各位体验(能提出意见更好嘿嘿) 体验地址: https://icon.999872.xyz/ 图片预览 👇...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
