Java反射(含静态代理模式、动态代理模式、类加载器以及JavaBean相关内容)

目录

1、什么是反射

2、Class类

3、通过Class类取得类信息/调用属性或方法

4、静态代理和动态代理

5.类加载器原理分析

6、JavaBean


1、什么是反射

Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。
一张图来表示:
如果编译不知道类或对象的具体信息,此时应该如何做呢?这时就要用到反射来实现。
Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。

2Class

在Java中,java.lang.Class 提供了在运行时访问对象的属性和类型信息的能力,可以说它是反射的入口。
Class 类可以理解为包含了很多类的类,其中它包括类名,构造方法,属性,方法。
得到Class类的对象有三种方式:
第一种形式:Object类中的getClass()方法
第二种形式:类.class
第三种形式:通过Class类的forName方法

用法示例:

public class Demo {private static Object Demo;public static void main(String[] args) throws ClassNotFoundException {person p1=new person();Class c=p1.getClass();//第一种形式:Object类中的getClass()方法System.out.println(c);System.out.println(person.class);//第二种形式:类.classClass aclass=Class.forName("person");//第三种形式:通过Class类的forName方法,需要抛出异常throws ClassNotFoundException}
}

使用Class类进行对象的实例化操作
调用无参构造进行实例化
public T newInstance() throws InstantiationException,IllegalAccessException

(JAVA 9 之后弃用 newInstance() 方法解决办法)
调用有参构造进行实例化
public Constructor<?>[] getConstructors() throws SecurityException

3、通过Class类取得类信息/调用属性或方法

取得类所在的包
public Package getPackage() //得到一个类所在的包
public String getName() //得到名字
取得一个类中的全部方法
public Method[] getMethods()
public int getModifiers() //Modifier.toString(mod); // 还原修饰符
public Class<?> getReturnType()
public Class<?>[] getParameterTypes()
public Class<?>[] getExceptionTypes()
public static String toString(int mod)
取得一个类中的全部属性
public Field[] getFields()
public Field[] getDeclaredFields()
public Class<?> getType()
public int getModifiers()
public String getName()
调用类中的方法
调用类中的方法,传入实例化对象,以及具体的参数内容
public Object invoke(Object obj,Object... args)
直接调用属性
取得属性
public Object get(Object obj)
// 设置属性,等同于使用“ = ”完成操作
public void set(Object obj,Object value)
// 让属性对外部可见
public void setAccessible(boolean flag)
(其中,带Declared的方法可以获取到私有属性或方法,不带Declared的只能获取公有属性或方法)

用法示例:

public class Demo {private static Object Demo;public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {Class p1=person.class;Field[] fields=p1.getDeclaredFields();//获取私有属性和公有属性,下同Field[] fields1=p1.getFields();//仅获取公有属性,下同for (Field f:fields){System.out.println(f);}System.out.println("-----------");for (Field f1:fields1){System.out.println(f1);}System.out.println("-----------");Method[] methods=p1.getDeclaredMethods();for (Method m1:methods) {System.out.println(m1);}System.out.println("-----------");Constructor[] constructor=p1.getDeclaredConstructors();for (Constructor c:constructor) {System.out.println(c);System.out.println(c.getName());System.out.println(c.getParameterCount());}System.out.println("-----------");Package p=p1.getPackage();System.out.println(p);for (int i = 0; i < fields.length; i++) {int mm=fields[i].getModifiers();System.out.println(mm+Modifier.toString(mm)+"/ /"+fields[i].getType()+"/ /"+fields[i].getName());}System.out.println("-----------");Constructor<?> constructor1=p1.getDeclaredConstructor();constructor1.setAccessible(true);person pp= (person) constructor1.newInstance();Method m3=p1.getMethod("run",String.class);m3.invoke(p1,"111");}}

4、静态代理和动态代理

代理模式(Proxy ):为其他对象提供一种代理以控制对这个对象的访问。
代理模式说白了就是“真实对象”的代表,在访问对象时引入一定程度的间接性,因为这
种间接性可以附加多种用途
静态代理:代理对象与目标对象一起实现相同的接口或者继承相同父类
动态代理:

 所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而
可以在运行期(Runtime)实现动态关联。
java动态代理主要是使用java.lang.reflect包中的两个类。
InvocationHandler类
public Object invoke(Object obj,Method method,Object[] obs)
其中第一个参数 obj 指的是代理类,method是被代理的方法,obs是指被代理的方法的参
数组。此方法由代理类来实现。
Proxy类
protected Proxy(InvocationHandler h);
static Class getProxyClass(ClassLoader loader,Class[] interfaces);
static Object newProxyInstance(ClassLoader loader,Class[]interfaces,InvocationHandler
h);
动态代理其实是在运行时生成class,所以,我们必须提供一组interface,然后告诉他class
已经实现了这些interface,而且在生成Proxy的时候,必须给他提供一个handler,让他
来接管实际的工作。

(静态代理)用法演示:

定义一个接口:

package com.company;public interface Action {public void doAction();
}

定义类:

package com.company;public class employee implements Action{@Overridepublic void doAction() {System.out.println("正在工作中...");}
}

定义静态代理类:

package com.company;public class Staticproxy {private Action target;public Staticproxy(Action target){this.target = target;}public void work(){System.out.println("开始上班");target.doAction();System.out.println("下班啦");}}

测试类:

package com.company;public class Main {public static void main(String[] args) {Action userAction = new employee();Staticproxy proxy = new Staticproxy(userAction);proxy.work();}
}

​​​​​​​
(动态代理)用法演示:

先定义两个接口:

package com.company;public interface Buytickets {public void buytickets();
}
package com.company;public interface Bookahotel {public void bookahotel();
}

 定义用户类:

package com.company;public class User implements Buytickets,Bookahotel{@Overridepublic void bookahotel() {System.out.println("开始预定酒店...");System.out.println("预定成功!");}@Overridepublic void buytickets() {System.out.println("开始买票...");System.out.println("购票成功!");}
}

定义代理类:

package com.company;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class CreatProxy implements InvocationHandler {private Object target;public Object creat(Object target){this.target=target;return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("现在开始你的业务...");method.invoke(target,args);System.out.println("完成本次业务!");return null;}
}

测试类:

package com.company;public class Main {public static void main(String[] args) {CreatProxy proxy=new CreatProxy();User user=new User();Bookahotel a= (Bookahotel) proxy.creat(user);a.bookahotel();}
}

 运行结果:

现在开始你的业务...
开始预定酒店...
预定成功!
完成本次业务!

5.类加载器原理分析

1、类的加载过程
JVM将类加载过程分为三个步骤:装载(Load),链接(Link)和初始化(Initialize)链接又分为三个步骤,如下图所示:
1) 装载:查找并加载类的二进制数据;
2)链接:
验证:确保被加载类的正确性;
准备:为类的静态变量分配内存,并将其初始化为默认值;
解析:把类中的符号引用转换为直接引用;



3)初始化:为类的静态变量赋予正确的初始值;
类加载器原理分析
2、类的初始化,类什么时候才被初始化:
1)创建类的实例,也就是new一个对象
2)访问某个类或接口的静态变量,或者对该静态变量赋值
3)调用类的静态方法
4)反射(Class.forName("com.vince.Dog"))
5)初始化一个类的子类(会首先初始化子类的父类)
6)JVM启动时标明的启动类,即文件名和类名相同的那个类
3、类的加载:
指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的Java.lang.Class对象,用来封装类在方法区类的对象。


6、JavaBean


什么是 JavaBean?
Bean理解为组件意思, JavaBean就是Java组件,在广泛的理解就是一个类,对于组件来
说,关键在于要具有“能够被IDE构建工具侦测其属性和事件”的能力。
一个JavaBean要具备这样的命名规则:
1、对于一个名称为xxx的属性,通常你要写两个方法:getXxx()和setXxx()。任何浏览这些
方法的工具,都会把get或set后面的第一个字母自动转换为小写。
2、对于布尔型属性,可以使用以上get和set的方式,不过也可以把get替换成is。
3、Bean的普通方法不必遵循以上的命名规则,不过它们必须是public的。
4、对于事件,要使用Swing中处理监听器的方式。如addWindowListener,
removeWindowListener
BeanUtils工具类:http://apache.org/

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

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

相关文章

java基础之面向对象的思想

一、面向对象和面向过程的编程思想对比 面向过程&#xff1a;是一种以过程为中心的编程思想&#xff0c;实现功能的每一步&#xff0c;都是自己实现的&#xff08;自己干活&#xff09;。 面向对象&#xff1a;是一种以对象为中心的编程思想&#xff0c;通过指挥对象实现具体的…

智慧生活:AI工具如何改变我们的工作与生活

文章目录 &#x1f4d1;前言一、常用AI工具&#xff1a;便利与高效的结合1.1 语音助手1.2 智能推荐系统1.3 自然语言处理工具 二、创新AI应用&#xff1a;不断突破与发展2.1 医疗诊断AI2.2 智能家居2.3 无人驾驶技术 三、AI工具在人们生活中的应用和影响3.1 生活方式的变化3.2 …

搭建本地yum仓库

步骤 找个地方存你的rpm包 #我创建了一个rpm文件夹存放我的rpm包 makdir -p /opt/repo/rpmcreaterepo 这个很重要&#xff0c;一定要安装 # 我的能连外网&#xff0c;所以直接yum安装&#xff0c;你的自己想办法 yum install createrepo -y创建repodata 安装了createrepo后…

SOA构架介绍

1.SOA定义 SOA面向服务的架构是一种计算机环境设计、开发、部署和管理离散模型的方法&#xff0c;SOA中所有的功能都被定义成立独立的服务&#xff0c;所有的服务通过总线&#xff08;ESB)或者流程管理连接。这种松耦合的结构使得服务器在交互的过程中无需考虑双方内部细节&am…

RocketMQ(一)

作用 1. 限流削峰 2. 异步解耦 组成 Producer&#xff1a;消息的发送者&#xff0c;生产者&#xff1b;举例&#xff1a;发件人 Consumer&#xff1a;消息接收者&#xff0c;消费者&#xff1b;举例&#xff1a;收件人 Broker&#xff1a;暂存和传输消息的通道&#xff1…

矩阵稀疏扫描 - 矩阵

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、Java代码五、测试用例提示 前言 本人最近再练习算法&#xff0c;所以会发布一些解题思路&#xff0c;希望大家多指教 一、题目描述 如果矩阵中的许多系数都为零&#xff0c;那么该矩阵就是稀…

Rust编程语言的特点及其适合做什么

Rust编程语言的特点 Rust是一门系统级编程语言&#xff0c;它有如下特点。 1. 类C的语言语法 Rust的具体语法和C/C类似&#xff0c;都是由花括号限定代码块&#xff0c;还有一样的控制流关键字&#xff0c;例如if、else、while和for。然而&#xff0c;也并非所有的C或者C关键…

Scratch四级:第07讲 编程数学02

第07讲 编程数学02 教练&#xff1a;老马的程序人生 微信&#xff1a;ProgrammingAssistant 博客&#xff1a;https://lsgogroup.blog.csdn.net/ 讲课目录 常考的数学问题项目制作&#xff1a;“求最大公约数”项目制作&#xff1a;“求最小公倍数”项目制作&#xff1a;“早餐…

RAG讲解

现有的LLM已经具备了理解、生成、逻辑和记忆能力&#xff0c;RAG(Retrieval Augmented Generation)则是为其套上外挂&#xff0c;使LLM能够访问训练数据来源之外的权威知识库&#xff0c;并生成领域特定的内容&#xff0c;而无须重新训练模型。 RAG的优势 经济高效&#xff1a…

Meilisearch使用过程趟过的坑

Elasticsearch 做为老牌搜索引擎&#xff0c;功能基本满足&#xff0c;但复杂&#xff0c;重量级&#xff0c;适合大数据量。 MeiliSearch 设计目标针对数据在 500GB 左右的搜索需求&#xff0c;极快&#xff0c;单文件&#xff0c;超轻量。 所以&#xff0c;对于中小型项目来说…

opencompass实践

参考教程 https://github.com/InternLM/Tutorial/blob/camp2/opencompass/readme.md 下载opencompass&#xff0c;配置必要的环境之后&#xff0c;解压下载的数据集 cp /share/temp/datasets/OpenCompassData-core-20231110.zip /root/opencompass/ unzip OpenCompassData-co…

如何远程操作服务器中的Python编译器并将运行结果返回到Pycharm

文章目录 一、前期准备1. 检查IDE版本是否支持2. 服务器需要开通SSH服务 二、Pycharm本地链接服务器测试1. 配置服务器python解释器 三、使用内网穿透实现异地链接服务器开发1. 服务器安装Cpolar2. 创建远程连接公网地址 四、使用固定TCP地址远程开发 本文主要介绍如何使用Pych…

RPA正常跑,cmd输入cookies跑不出来,如何解决??

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

SQL-递归查询

运行环境&#xff1a; Mysql8以上&#xff0c;递归查询功能在8以上版本被正式引入 一、SQL递归查询的概念 递归指的是通过调用函数或过程或自身来解决问题的方法&#xff0c;常用于一些具有规律性循环的操作。SQL递归查询是基于一组初始数据&#xff0c;通过递归查询&#xf…

机器人系统ros2-开发实践06-将静态坐标系广播到 tf2(Python)-定义机器人底座与其传感器或非移动部件之间的关系

发布静态变换对于定义机器人底座与其传感器或非移动部件之间的关系非常有用。例如&#xff0c;最容易推断激光扫描仪中心框架中的激光扫描测量结果。 1. 创建包 首先&#xff0c;我们将创建一个用于本教程和后续教程的包。调用的包learning_tf2_py将依赖于geometry_msgs、pyth…

【机器学习】集成学习在信用评分领域实例

集成学习在信用评分领域的应用与实践 一、引言二、集成学习的概念与原理三、集成学习在信用评分中的应用实例四、总结与展望 一、引言 在当今金融数字化快速发展的时代&#xff0c;信用评分成为银行、金融机构等评估个人或企业信用风险的重要工具。然而&#xff0c;单一的信用评…

WebRTC 中的 ICE 实现

WebRTC 中的 ICE 实现 WebRTC 中的 ICE 实现Candidate 种类与优先级ICE 策略P2P 连接完全锥型 NATIP 限制锥型 NAT端口限制锥型 NAT对称型 NATNAT 类型检测如何进行 NAT 穿越 网络中继TURN 协议中转数据WebRTC 使用 TURN 协议STUN/TURN 服务器的安装与部署 WebRTC 中的 ICE 实现…

如何打破数据管理僵局,释放数据资产价值?[AMT企源案例]

引言 数据是企业信息运作的核心和基础&#xff0c;是影响企业决策的关键要素&#xff0c;而主数据是数据中的最基础和公共的部分。面临长期以来的数据治理缺失导致的杂论局面&#xff0c;如何有条不紊推进主数据管理&#xff0c;让数据资产“活”起来&#xff1f;S集团的做法非…

torch_geometric安装(CPU版本)

①打开官方安装网址&#xff1a;https://pytorch-geometric.readthedocs.io/en/2.3.0/install/installation.html ②对根据Pytorch选择相应版本。此前一直用CUDA不成功&#xff0c;这次使用CPU版本&#xff08;因为不用对应cuda&#xff0c;pytorchcudageometric三者对应起来很…

[数据结构]动画详解单链表

&#x1f496;&#x1f496;&#x1f496;欢迎来到我的博客&#xff0c;我是anmory&#x1f496;&#x1f496;&#x1f496; 又和大家见面了 欢迎来到动画详解数据结构系列 用通俗易懂的动画的动画使数据结构可视化 先来自我推荐一波 个人网站欢迎访问以及捐款 推荐阅读 如何低…