Java19:反射

一:反射的理解

Reflection(反射)是指被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API 取得任何类的内部信息,并直接操作任意对象的内部属性及方法。

框架=反射+注解+设计模式

二:体会反射机制的“动态性”

// 创建一个指定类的对象,classpath:指定类的全类名
public  Object getInstance(String classpath) throws Exception {Class clazz = Class.forName(classpath);return clazz.newInstance();
}@Test
public void test2()  {Random random = new Random();String classpath="";for (int i = 0; i < 100; i++) {int number = random.nextInt(3);switch (number) {case 0:classpath = "java.util.Date";break;case 1:classpath = "java.lang.Object";break;case 2:classpath = "com.cn.test.Person";break;}try {Object obj=getInstance(classpath);System.out.println(obj);} catch (Exception e) {e.printStackTrace();}}
}

三:反射机制能提供的功能

》在运行时判断任意一个对象所属的类

》在运行时构造任意一个类的对象

》在运行时判断任意一个类所具有的成员变量和方法

》在运行时获取泛型信息

》在运行时调用任意一个对象的成员变量和方法

》在运行时处理注解

》生成动态代理

四:相关API

java.lang.Class  :反射的源头

java.lang.reflect.Method

java.lang.reflect.Field

java.lang.reflect.Constructor

五:关于Class类的理解

1.类的加载过程:

程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾)。

接着我们使用java.exe 命令 对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中,在此过程就称为类的加载。加载到内存中的类,我们称为运行时类,此运行时类,就作为Class 的一个实例。

2.换句话说,Class的实例 对应着 一个运行时类。

3.加载到内存中的运行时类会缓存一定的时间,在此时间之内,我们可以通过不同方式来获取此运行时类。

4.获取Class实例的几种方式:

@Test
public void test3() throws ClassNotFoundException {//1.调用类.class 属性,获取Class实例Class class1= Person.class;System.out.println(class1);Person p =new Person();//2.调用getClass(),获取Class实例Class class2= p.getClass();System.out.println(class2);//3.Class.forName,获取Class实例  Class class3 = Class.forName("com.cn.test.Person");System.out.println(class3);//4.调用类的加载器getClassLoader(),获取Class实例ClassLoader classLoader = Reflection1Test.class.getClassLoader();Class class4= classLoader.loadClass("com.cn.test.Person");System.out.println(class4);//System.out.println(class1==class2);

5. 总结:创建类的对象的方式

方式一: new + 构造器

方式二:要创建Xxx类的对象,可以考虑:Xxx/Xxxs 类是否有静态方法存在,可以调用其静态方法,创建Xxx对象。

方式三:通过反射

6.Class实例可以是哪些结构的说明

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

2)interface:接口

3) []:数组

4)enum:枚举

5)annotation:注解@interface

6)primitive type:基本数据类型

7)void

7.类的加载器,加载配置文件

@Test
public void test3() throws IOException {//方式一Properties pro =new Properties();FileInputStream fis =new FileInputStream("jdbc.propertities");pro.load(fis);String name = pro.getProperty("name");String age = pro.getProperty("age");System.out.println(name+":"+age);}
@Test
public void test4() throws IOException {//方式二,该方式文件放在src目录下ClassLoader classLoader = Reflection2Test.class.getClassLoader();InputStream resourceAsStream = classLoader.getResourceAsStream("jdbc2.propertities");Properties pro =new Properties();pro.load(resourceAsStream);String name = pro.getProperty("name");String age = pro.getProperty("age");System.out.println(name+":"+age);}

六:反射的实例

1.获取所有的属性,方法,构造器

@Test
public void test2() {Class clazz = Person.class;//获取运行时类及其所有父类的public方法Method[] methods = clazz.getMethods();for (Method m : methods) {System.out.print(m + "\t");System.out.println(m.getName());}System.out.println();//获取运行时类所有方法Method[] declaredMethods = clazz.getDeclaredMethods();for (Method m : declaredMethods) {System.out.print(m + "\t");System.out.println(m.getName());}}@Test
public void test3() {Class clazz = Person.class;//获取运行时类所有public的构造器Constructor[] constructors = clazz.getConstructors();for(Constructor c:constructors){System.out.println(c);}System.out.println();//获取运行时类所有构造器Constructor[] constructors2 = clazz.getDeclaredConstructors();for(Constructor c:constructors2){System.out.println(c);}}
@Test
public void test4() throws Exception {//获取当前运行时类父类的对象Class superclass = Person.class.getSuperclass();System.out.println(superclass);

}

2.获取指定的属性,方法,构造器

@Test
public  void filedTest() throws Exception {Class clazz=Person.class;Object obj = clazz.newInstance();Person per= (Person) obj;//获取指定属性Field name = clazz.getDeclaredField("name");//给指定对象属性复制name.set(per,"tom");System.out.println(name.get(per));//给静态属性赋值,并获取Field hobbies = clazz.getDeclaredField("hobbies");hobbies.set(clazz,"baskball");System.out.println(hobbies.get(clazz));
}@Test
public  void methodTest() throws Exception {Class clazz=Person.class;Object obj = clazz.newInstance();Person per= (Person) obj;//获取public 无参方法 并调用Method info = clazz.getDeclaredMethod("info");info.invoke(per);//获取public 有参方法 并调用Method getNation = clazz.getDeclaredMethod("getNation",String.class);getNation.invoke(per,"china");//获取静态方法并调用Method study = clazz.getDeclaredMethod("study");study.invoke(clazz);//获取私有方法并调用Method getAge = clazz.getDeclaredMethod("getAge", int.class);//设置为可访问getAge.setAccessible(true);System.out.println(getAge.invoke(per, 20));}@Test
public  void ConstructTest() throws Exception {Class clazz= Person.class;//该方法为常用用法,具有通用性Object o = clazz.newInstance();System.out.println(o);//获取带有参数的构造器,不常用Constructor constructor = clazz.getDeclaredConstructor(int.class, String.class);constructor.setAccessible(true);Object jerry = constructor.newInstance(15, "jerry");System.out.println(jerry);}



七:反射的应用:动态代理

1.静态代理:

interface ColthFactory{void  produceColth();
}
//代理类
class ProxyColthFactory implements ColthFactory{private ColthFactory factory;public ProxyColthFactory(ColthFactory factory){this.factory=factory;}@Overridepublic void produceColth() {System.out.println("生产衣服之前的准备工作");factory.produceColth();System.out.println("生产衣服之后的收尾工作");}
}
//被代理类
class NIkeColthFactory implements  ColthFactory{@Overridepublic void produceColth() {System.out.println("NIKE生产衣服");}
}public class StaticProxyTest {public static void main(String[] args) {//创建被代理类对象NIkeColthFactory nike =new NIkeColthFactory();//创建代理类对象ProxyColthFactory proxy =new ProxyColthFactory(nike);//调用方法proxy.produceColth();}
}

2.动态代理:

class ProxyFactory{public static Object getInstance(Object obj){MyInvocationHandler hander= new MyInvocationHandler();hander.blind(obj);return  Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), hander);}
}class MyInvocationHandler implements InvocationHandler{private Object obj; //赋值时必须传被代理类实例public void blind(Object obj){this.obj=obj;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object invoke = method.invoke(obj, args);// method为代理类调用的方法,此方法也作为被代理类对象要调用的方法return invoke;}
}public class ProxyTest {public static void main(String[] args) {NIkeColthFactory nike = new NIkeColthFactory();ColthFactory  colthFactory= (ColthFactory) ProxyFactory.getInstance(nike);colthFactory.produceColth();}
}

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

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

相关文章

Debian11下编译ADAravis和Motor模块的一条龙过程

Debian11编译EPICS ADAravis记录 一年前整理的上面文&#xff0c;这几天重新走了一遍&#xff0c;有些地方会碰到问题&#xff0c;需要补充些环节&#xff0c;motor模块以前和areaDetector一条龙编译时&#xff0c;总是有问题&#xff0c;当时就没尝试了&#xff0c;这几天尝试…

位运算的魅力:使用Redis Bitmap高效处理百万级布尔值

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 位运算的魅力&#xff1a;使用Redis Bitmap高效处理百万级布尔值 前言1. Bitmap的基本概念Bitmap的定义和原理为什么Bitmap特别适合处理大量布尔值 2. Redis中的Bitmap操作基础命令高级命令 实际应用场…

IDCNN(迭代扩张卷积神经网络)在NLP-NER任务中的应用

IDCNN&#xff08;迭代扩张卷积神经网络&#xff09;在NLP-NER任务中的应用 IDCNN&#xff08;Iterated Dilated Convolutional Neural Network&#xff09;是一种特别设计的卷积神经网络&#xff08;CNN&#xff09;&#xff0c;用于处理自然语言处理&#xff08;NLP&#xf…

低压防雷箱综合选型应用方案

低压防雷箱是一种用于保护低压配电系统免受雷电过电压的影响的装置&#xff0c;它主要由防雷箱模块、浪涌保护器SPD、接地线等组成。本文将介绍低压防雷箱的作用原理和行业应用解决方案&#xff0c;以及低压防雷箱的选型方法。 低压防雷箱的作用原理 低压防雷箱的作用原理是利…

股东出资透明度提升:企业股东出资信息API的应用

前言 在当今商业环境中&#xff0c;股东出资信息的透明度对于投资者、监管机构以及企业自身的健康发展至关重要。随着企业信息公开化的推进&#xff0c;企业股东出资信息API应运而生&#xff0c;为各方提供了一个便捷、高效的信息获取渠道。本文将探讨企业股东出资信息API如何…

HCIA NAT练习

目录 实验拓扑 实验要求 实验步骤 1、IP分配 2、使用ACL使PC访问外网 3、缺省路由 4、边界路由器公网ip端口配置 测试 实验拓扑 实验要求 1、R2为ISP路由器&#xff0c;其上只能配置ip地址&#xff0c;不得再进行其他的任何配置 2、PC1-PC2可以ping通客户平板和DNS服…

【OJ】牛客链表刷题

题目 1. 链表分割1.1 题目分析1.2 代码 2. 链表的回文结构2.1 题目分析2.2 代码 这里两道与链表有关的题目均来自牛客。 1. 链表分割 1.1 题目分析 因为这里代码不能选择用c语言写&#xff0c;所以选择用c,因为c兼容c。 题目要求分割链表&#xff0c;我们可以直接弄成两个带哨…

基于CanvasLabel的Leaflet矢量数据免切片属性标注实践

目录 前言 一、Leaflet.CanvasLabel 1、开源地址 2、设置参数说明 二、组件集成 1、新建html文件 2、声明样式 3、定义矢量文本渲染器 4、定义地图 5、添加矢量数据 6、最终效果 总结 前言 在一般的业务场景中&#xff0c;针对小量的矢量数据&#xff0c;比如POI兴…

云轴科技ZStack位列IDC云系统软件市场教育行业TOP2

近日&#xff0c;全球IT市场研究和咨询公司IDC发布 《中国云系统软件市场跟踪报告2023H1》 ZStack作为产品化的云基础软件提供商 位居云系统软件市场第一梯队 市场份额位列独立云厂商*第一 营收同比增速最快 教育行业TOP2 在教育行业&#xff0c;云计算已成为教育行业信息化的…

Python 安装 QtDesigner

Python 安装 QtDesigner 对于最新版本的 PyQt6 模块&#xff0c;可以直接使用如下代码来安装 Designer 软件。 pip install PyQt6-tools 安装好以后&#xff0c;需要到 Python 安装目录中寻找对应的启动 exe 文件。 C:\Softwares\Python 3.11.5\Lib\site-packages\qt6_applica…

[小程序]页面事件

一、下拉刷新 1.开启和配置 小程序中开启下拉刷新的方式有两种&#xff1a; ①全局开启下来刷新 在app.json的window节点中&#xff0c;设置enablePullDownRefresh设为ture。 ②局部开启下来刷新 在页面对应的json文件的的window节点中&#xff0c;设置enablePullDownRefresh设…

Qt应用开发(安卓篇)——Hello Qt On Android

一、前言 这一篇从实际出发&#xff0c;讲述如何创建、编译和部署Qt On Android项目。 二、ADB调试 ADB的全称为Android Debug Bridge&#xff0c;就是起到调试桥的作用&#xff0c;主要用于连接计算机与Android 设备&#xff0c;以便进行调试和数据传输。ADB 可以实现以下主要…

uniapp组件库SwipeAction 滑动操作 使用方法

目录 #平台差异说明 #基本使用 #修改按钮样式 #点击事件 #API #Props #Event 该组件一般用于左滑唤出操作菜单的场景&#xff0c;用的最多的是左滑删除操作。 注意 如果把该组件通过v-for用于左滑删除的列表&#xff0c;请保证循环的:key是一个唯一值&#xff0c;可以…

HNU-数据挖掘-实验3-图深度学习

数据挖掘课程实验实验3 图深度学习 计科210X 甘晴void 202108010XXX 文章目录 数据挖掘课程实验<br>实验3 图深度学习实验背景实验要求数据集解析实验内容&#xff08;0&#xff09;基础知识&#xff1a;基于图的深度学习方法浅识&#xff1a;图卷积网络 (GCN)浅识&…

【Linux】第三十二站:命名管道

文章目录 一、命名管道介绍二、编码1.mkfifo2.unlink3.一个简单的例子4.修改 一、命名管道介绍 管道应用的一个限制就是只能在具有共同祖先&#xff08;具有亲缘关系&#xff09;的进程间通信。 如果我们想在不相关的进程之间交换数据&#xff0c;可以使用FIFO文件来做这项工作…

14 STM32 - IIC (时序图+软件源码)

14.1 IIC简介 IIC&#xff08;Inter-Integrated Circuit&#xff09;&#xff0c;中文集成电路总线&#xff0c;是一种串行通信总线&#xff0c;使用多主从架构。I2C串行总线一般有两根信号线&#xff0c;一根是双向的数据线SDA&#xff0c;另一根是时钟线SCL。所有接到I2C总线…

【蓝桥杯备赛Java组】语言基础|竞赛常用库函数|输入输出|String的使用|常见的数学方法|大小写转换

&#x1f3a5; 个人主页&#xff1a;深鱼~&#x1f525;收录专栏&#xff1a;蓝桥杯&#x1f304;欢迎 &#x1f44d;点赞✍评论⭐收藏 目录 一、编程基础 1.1 Java类的创建 1.2 Java方法 1.3 输入输出 1.4 String的使用 二、竞赛常用库函数 1.常见的数学方法 2.大小写转…

邦芒支招:避免薪资谈崩的六个措施

对于求职者而言&#xff0c;我喜欢把回答薪资问题比喻成玩扑克牌&#xff0c;它的目标就是让招聘方先亮出底牌。其原因在于&#xff0c;正如詹姆斯察觉到的&#xff0c;一旦你暴露了具体的薪资数目&#xff0c;你就会陷入要价太高(或者太低)的境地。 以下这些小技巧也许能为…

函数传参之按值传递

定义&#xff1a;所有函数的参数都是按值传递的&#xff0c;这意味着函数外的值被会被赋值到函数内部的参数中&#xff0c;就像从一个变量赋值到另外一个变量一样 **原始值&#xff1a;那么久跟原始值变量的复制一样** **引用值&#xff1a;那么久跟引用值复制一样**变量有按值…

php基础学习之代码框架

一&#xff0c;标记 脚本标记&#xff08;已弃用&#xff09;&#xff1a;<script language"php"> php代码 </script> 标准标记&#xff1a;<?php php代码 ?> 二&#xff0c;基础输出语句 不是函数&#xff0c;…