java框架第二课(Reflection反射机制)

一.关于反射

(1)使用场景介绍

平常我们写代码时,都是已知类名,类的属性,构造方法,其他方法等信息,然后根据类名new对象,这个过程称为正向操作(例如:有一个管理员类,有账号和密码属性,还有一个set,get,eat方法,直接通过类名new对象,再通过对象名调用类的变量和方法。但在其他的一些场景如框架,servlet,xml文件中,可能并不知道该类有什么属性和方法等,可能只知道类的名字等,无法直接new对象为解决这个问题就引入了反射机制。

(1)如:servlet中的json格式转换将对象转为{属性名,值}的字符串

new ObjectMapper().writeValueAsString(result)    result就是传入的对象,json处理时并不知道这个传入的对象是什么,所以就要反过来根据对象名拿到该对象类的变量和属性,才能获得该对象的属性名和值。

(2) 如:在mybatis框架中要在mybatis的xml文件中配置类的名称从而找到类,将查询的结果自动通过类的名称映射到类的对象中,这就是使用了反射机制。

<insert id="insertAdminById" parameterType="Admin">insert into admin(account,password,gender) values (#{account},#{password},#{gender})
</insert>

(2)什么是java反射 

java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。

(3)在java中为什么要使用反射

就在上述场景中介绍一样,在java中平常不可避免的要用到反射,平常写业务代码(就是自己创建类new 对象,自己清楚类的属性和方法)用不到,但是一些其他场景不可避免地可能只知道类名,对象名等,要对该类(对象)的属性,方法操作就需要动态获取类(对象)的信息,使其只要知道任意类名或者对象名就能获得该类或者该对象的属性和方法并对其进行操作。

(4)反射机制图解

(5)java反射相关api

Java反射相关的类主要包括
Class 类型  :  可以动态将任意类转化为Class对象,然后根据Class对象获得类的对象)。
Constructor 构造方法 :可以通过该构造方法获得类的对象(前提获得Class对象)。
Method 方法 :  获得类的方法(前提获得Class对象)。
Field 属性:         获得类的属性(前提获得Class对象)。
除了Class外,其他类都位于java.lang.reflect包中
可见,反射API将类的类型、方法、属性都封装成了类,其中最重要的类是 Class,可以说,反射的使用都是从Class开始。

 以user(管理员类为例)

package com.ffyc.javareflection.model;public class user {String account;String password;public user() {System.out.println("无参构造方法");}public void eat(){System.out.println("人吃饭");}public user(String account, String password) {System.out.println("有参构造方法");this.account = account;this.password = password;}public String getAccount() {return account;}public void setAccount(String account) {this.account = account;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "user{" +"account='" + account + '\'' +", password='" + password + '\'' +'}';}
}

1.获得Class对象 

  已知类如何获得类中的属性和方法,通过CLass获得//方法一:已知类名获得Class对象Class aClass=Class.forName("com.ffyc.javareflection.model.user");System.out.println(aClass);//方法二:已知类获得Class对象Class bclass=user.class;System.out.println(bclass);//方法三:已知对象名获得Class对象user user=new user();Class cclass=user.getClass();System.out.println(cclass);

结果如图Class对象一样 

  获得类的对象有四种方法:
      1.new 对象2.对象序列化 3.反射机制4.对象克隆

2.通过Class对象获得类的对象 

  //第一种:通过Class对象中的new获得类的对象Class aaclass=Class.forName("com.ffyc.javareflection.model.user");Object object=aaclass.newInstance();System.out.println(object);

3.通过构造方法获得类的对象

//第二种:通过类中的构造方法来获得类的对象(公共的构造方法)//无参构造Constructor constructor=aaclass.getConstructor();Object object1= constructor.newInstance();System.out.println(object1);//有参构造Constructor constructor1=aaclass.getConstructor(String.class,String.class);Object object2=constructor1.newInstance("张三","111");System.out.println(object2);//获得所有公共的构造方法Constructor []constructors=aaclass.getConstructors();System.out.println(constructors.length);//获得任意的构造方法,包含私有的构造方法,一般不建议操作,因为打破了封装性Constructor [] constructor3=  aaclass.getDeclaredConstructors();System.out.println(constructor3.length);

4. 通过Method 方法获得类的方法(Method getMethod(String name, Class... parameterTypes) : 通过指定方法名,参数类型,返回一个Method实例)

Method 作用:

Method类将类中的方法进行封装,可以动态获得方法的信息,例如
getName:获得方法名字
getParameterTypes:获得方法参数类型
除了动态获得方法信息外,Method还能动态调用某一个对象的具体方法
invoke(Object obj, Object... args) :使用obj调用该方法,参数为args
        Class cclass=Class.forName("com.ffyc.javareflection.model.user");Object object=cclass.newInstance();Method method=cclass.getMethod("eat");String value= (String) method.invoke(object);System.out.println(value);

 

 5.Field 属性获得类的属性

Field类将类的属性进行封装,可以获得属性的基本信息、属性的值,也可以对属性进行赋值.
getName:返回属性的名字
set:设置属性值

 

 //通过私有属性get和set放法对类中私有属性进行赋值取值操作HashMap<String,String> hashMap=new HashMap<>();hashMap.put("account","admin");hashMap.put("password","111");Field [] fields=cclass.getDeclaredFields();//获得类中所有的成员变量包括私有的for (Field field:fields) {//根据属性名获得set放法名称String setmethod="set"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);//通过class对象获得set方法对象Method method=  cclass.getMethod(setmethod,field.getType());//调用set方法method.invoke(object,hashMap.get(field.getName()));}System.out.println(object); //通过私有属性get和set放法对类中私有属性进行赋值取值操作HashMap<String,String> hashMap=new HashMap<>();hashMap.put("account","admin");hashMap.put("password","111");Field [] fields=cclass.getDeclaredFields();//获得类中所有的成员变量包括私有的for (Field field:fields) {//根据属性名获得set放法名称String setmethod="set"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);//通过class对象获得set方法对象Method method=  cclass.getMethod(setmethod,field.getType());//调用set方法method.invoke(object,hashMap.get(field.getName()));}System.out.println(object);

二.反射的实例转json格式

package com.ffyc.javareflection.model;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class Json {public static String json(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {String json="{";Class aclass=object.getClass();//先将传过来的对象转为class对象Field[] fields=aclass.getDeclaredFields();//然后获得该对象的所有属性for (Field field:fields) {String getfield="get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);//拿到get方法名//获得方法对象,getMethod(方法名,返回值类型)Method method= aclass.getMethod(getfield);//调用方法String value=(String)method.invoke(object);//把属性名和值拼接成键值json+=json+field.getName()+":"+value+",";json=json.substring(0,json.length()-1);//去掉多余逗号json+="}";}return json;}public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {car car = new car();car.setName("红旗");car.setColor("红色");user user = new user();user.setAccount("admin");user.setPassword("111");System.out.println(Json.json(car));System.out.println(Json.json(user));}
}

 

三.反射的好处和坏处 

  优点:
● 1. 增加程序的灵活性,可以在运行的过程中动态对类进行修改和操作
● 2. 提高代码的复用率,比如动态代理
● 3. 可以在运行时轻松获取任意一个类的方法、属性,并且还能通过反射进行动态调用

 缺点:

● 1. 反射会涉及到动态类型的解析,导致性能要比非反射调用更低
● 2. 使用反射技术通常要在一个没有安全限制的程序运行 .
● 3. 反射可以绕过一些限制访问的属性或者方法,可能会导致破坏代码本身的抽象 性

 

 

 

 

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

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

相关文章

【SQL】三角形判断

目录 题目 分析 代码 题目 表: Triangle ------------------- | Column Name | Type | ------------------- | x | int | | y | int | | z | int | ------------------- 在 SQL 中&#xff0c;(x, y, z)是该表的主键列。 该表的每一行包…

Sigmoid 函数及其导数推导

Sigmoid 函数及其导数推导 1. 了解 Sigmoid 函数 Sigmoid 函数是神经网络中常用的激活函数&#xff0c;因其平滑的S形曲线和将输入压缩至 (0, 1) 的特性&#xff0c;在神经网络的激活函数中扮演着重要角色。其定义如下&#xff1a; σ ( x ) 1 1 e − x \sigma(x) \frac{1…

【应用开发】解决正点原子I.MX6ull应用编程zlib移植问题

问题描述 在正点原子应用开发移植zlib库的时候&#xff0c;文档中有这样一段描述&#xff0c;先删除开发板中的zlib库&#xff0c;然后再拷贝zlib库 这就会导致在使用scp命令拷贝编译好的zlib库的时候报错没有zlib.so.1&#xff0c;如下图所示&#xff1a; 解决方法 千万不…

安卓好软-----手机端提取apk的小工具 方便简单 无需root权限

apk提取工具 工具小巧。可以提取手机上面当前安装的apk和系统应用apk。而且无需root权限即可正常使用。 效果非常不错。比其他工具提取系统app方便好使。 下载&#xff1a;https://download.csdn.net/download/mg668/89683199?spm1001.2014.3001.5503

详解ACL限制SSH、Telnet远程登录及抓包实验

要求&#xff1a;lsw5只能lsw6登录&#xff0c;lsw6只能PC2登录 <Huawei>sys [Huawei]sysname sw2 [sw2]int vlanif1 [sw2-Vlanif1]ip address 192.168.10.2 24 [sw2-Vlanif1]q [sw2] <Huawei>sys [Huawei]sysname sw1 [sw1]int vlanif1 [sw1-Vlanif1]ip address …

视频单条剪、脚本靠手写?云微客开启海量视频时代

老板们注意了&#xff0c;现在已不再是视频单条剪&#xff0c;脚本靠手写的时代&#xff01;在这个信息爆炸的时代&#xff0c;短视频已经成为了现代信息传播和娱乐消费的重要载体&#xff0c;那么我们该如何高效、快速地制作出大量高质量的短视频内容呢&#xff1f;这就需要云…

面试必备:接口自动化测试精选面试题大全

一、 请问你是如何做接口测试的&#xff1f; 大体来说&#xff0c;经历以下过程&#xff1a;接口需求调研、接口测试工具选择、接口测试用例编写、接口测试执行、接口测试回归、接口测试自动化持续集成。具体来说&#xff0c;接口测试流程分成以下九步&#xff1a; 第一步&am…

SpringBoot集成kafka开发-消息消费的分区策略(消费者如何判断从哪个分区中消费消息的?)

这里写目录标题 1、kafak消息者消费消息的4种分区策略2、kafka默认的消费分区策略1-RangeAssignor&#xff08;均匀分配、默认分配策略&#xff09;2.1、代码验证RangeAssignor的消息分区策略2.1.1、消费者2.1.2、生产者2.1.3、kafak配置类2.1.4、对象实体类2.1.5、项目配置文件…

基于vue框架的病床管理信息系统odt4v(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 开题报告内容 基于Vue框架的病床管理信息系统开题报告 一、引言 随着医疗技术的不断进步和人口老龄化的加剧&#xff0c;医院面临着日益增长的医疗服务需求。病床作为医院资源的重要组成部分&#xff0c;其管理效率直接影响到患者的就医体验和医院的运营效…

TCP/UDP的对比,粘包分包抓包,http协议

服务器端&#xff1a; 一、loop 127.0.0.1本地回环测试地址 二、tcp特点 面向连接、可靠传输、字节流 粘包问题&#xff1a;tcp流式套接字&#xff0c;数据与数据之间没有套接字&#xff0c;导致可能多次的数据粘到一起 解决方法&#xff1a;&#xff08;1&#xff09;规…

使用USB转485转接器,从机不响应

在调试485通信时&#xff0c;bms不响应主机&#xff0c;usb转485转换器接收指示灯常亮&#xff0c;现象如下&#xff0c;通过更新驱动程序解决。 更新驱动程序链接&#xff1a; 1. 下载并解压驱动文件 https://www.szutek.com/Uploads/file/20210917/20210917091627_42822.rar…

生信圆桌:专业生信服务器与平台服务的提供者

生信圆桌是一个专注于提供生物信息学&#xff08;生信&#xff09;服务器和平台服务的领先企业&#xff0c;致力于为全球科研机构、企业和独立研究者提供高性能的生信分析解决方案。随着生物信息学研究对计算资源的需求日益增加&#xff0c;生信圆桌凭借其先进的服务器技术和专…

【QT学习】1-2 Liunx环境下QT5.12.9软件安装1——VMware17.0.0虚拟机安装

注意&#xff1a;如果电脑已经安装低版本的VMware&#xff0c;千万不要卸载&#xff0c;直接覆盖安装&#xff0c;更新到新的安装版本 1.点击.exe文件&#xff0c;右键以管理员身份运行&#xff0c;点击下一步&#xff0c;下一步 2.选择软件安装位置后&#xff0c;点击下一步。…

虚幻5|制作一个木桩,含血量及伤害数字

一&#xff0c;基础设置 1.创建Actor蓝图类 2.编辑胶囊体和网格体的碰撞预设 3.打开敌人的角色蓝图&#xff0c;编辑飙血特效 二&#xff0c;创建敌人血量的ui&#xff0c;命名为敌人血量&#xff0c;如下 1. 2&#xff0c;打开后&#xff0c;添加一个画布画板和进度条&#…

ArkUI-布局(一)

ArkUI-布局 布局概述布局元素的组成如何选择布局布局位置对子元素的约束 线性布局部分属性与使用方式 层叠布局部分属性与使用方式 弹性布局基本概念布局方向布局换行主轴对齐方式交叉轴对齐方式容器设置交叉轴对齐方式子元素设置交叉轴对齐方式内容对齐 自适应拉伸 布局概述 …

云端集中管控边缘服务:利用 EMQX ECP 在 K8s 上快速部署 NeuronEX

随着物联网、边缘计算技术的发展&#xff0c;实现边缘服务的快速部署对于分布式计算环境至关重要。它不仅可以显著降低延迟、节省带宽资源、增强数据的安全性和隐私保护&#xff0c;同时还能改善用户体验&#xff0c;支持动态变化的工作负载需求&#xff0c;提供更高的灵活性和…

JAVA毕业设计165—基于Java+Springboot+vue3的二手房交易管理系统(源代码+数据库+11000字论文)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootvue3的二手房交易管理系统(源代码数据库11000字论文)165 一、系统介绍 本项目前后端分离(还有ssm版本)&#xff0c;分为用户、卖家、管理员三种角色 1、用户&a…

TOMCAT-企业级WEB应用服务器

一 WEB技术 1.1 HTTP协议和B/S 结构 HTTP&#xff08;HyperText Transfer Protocol&#xff09;协议即超文本传输协议&#xff0c;是用于在万维网&#xff08;WWW&#xff09;上传输超文本内容的基础协议。 一、HTTP 协议的特点 1、简单快速 客户向服务器请求服务时&#…

leetcode234. 回文链表(java实现)

题目描述&#xff1a; 本道题的思路可以使用集合先存储链表的值&#xff0c;然后进行判断即可。 总体思路比较简单。 代码实现&#xff1a; class Solution {public boolean isPalindrome(ListNode head) {List<Integer> res new ArrayList();ListNode cur head;whil…

代谢组数据分析(十八):随机森林构建代谢组诊断模型

介绍 使用随机森林算法和LASSO特征选择构建了一种胃癌(GC)诊断预测模型。参与者(队列1,n=426)通过随机分层抽样分为发现数据集(n=284)和测试集(n=142)。接下来,在发现数据集上执行LASSO回归,以选择能够识别胃癌患者的较少数量的特征。我们将L1约束的系数设置为0.01…