(四)Spring教程——控制反转或依赖注入与Java的反射技术

        IoC的底层实现技术是反射技术,目前Java、C#、PHP 等语言均支持反射技术。

        在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法;对任意一个对象,都能够调用它的任意方法和属性(包括私有的方法和属性)。这种动态获取信息以及动态调用对象对象和对象方法的功能就被称作反射机制。

        通俗来讲,反射技术就是根据给出的类名(字符串方式)来动态生成对象。这种编程方式可以在生成对象时再决定到底生成哪一种对象。反射的应用是很广泛的,很多成熟的框架都离不开反射技术,比如Java中的Hibernate、Spring框架。

        反射技术很早就出现了,初期的反射编程速度相对于传统对象生成速度至少要慢10倍,目前的反射技术经过优化,反射方式生成对象和传统对象生成方式的速度相差不大,大约有1~2被的差距。由于IoC容器通过反射方式生成对象时,在运行效率上有一定的损耗,因此,如果系统追求运行效率,就必须权衡是否使用反射技术。

        在Java语言中,可以通过Class类的forName()方法获取类的信息,同Class类的newInstance()方法获得一个具体的实例。在java.lang.reflect包里,Java语言提供了Field、Method、Modifier、Constructor、InvocationHandler等类,可以轻松实现反射技术。

        为了让大家了解依赖注入的基础,示例展示了使用Java实现的一个反射应用:通过Class类来实现类的定义,通过Field来获取类的属性,通过Method类来获取方法,并通过invoke来调用方法,设置类的某个属性。

        首先我们创建一个InnerPerson类,InnerPerson类的代码如下

class InnerPerson {private String name;private int age;public String pub;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "reflect.InnerPerson{" +"name='" + name + '\'' +", age=" + age +'}';}};

        然后我们创建一个ReflectDemo01类,在该类中我们使用三种方式来实现类的实例化。ReflectDemo1的代码如下图所示

public class ReflectDemo01 {public static void main(String[] args) {//三种不同类实例化方法//第一种实例Class<?> firstInstance = null;//第二种实例Class<?> secondInstance = null;//第三种实例Class<?> thirdInstance = null;//通过类名实例化的方法try {firstInstance = Class.forName("com.example.servlet001.InnerPerson");} catch (ClassNotFoundException e) {e.printStackTrace();}//通过Object类中的方法实例化secondInstance=new InnerPerson().getClass();//通过类.class实例化thirdInstance=InnerPerson.class;System.out.println("类名称:"+firstInstance.getName());System.out.println("类名称:"+secondInstance.getName());System.out.println("类名称:"+thirdInstance.getName());}}

        运行该程序后得到的结果如下图所示

        继续修改ReflectDemo01 的代码,代码内容如下

public class ReflectDemo01 {public static void main(String[] args) {//三种不同类实例化方法//第一种实例Class<?> firstInstance = null;//第二种实例Class<?> secondInstance = null;//第三种实例Class<?> thirdInstance = null;//通过类名实例化的方法try {firstInstance = Class.forName("com.example.servlet001.InnerPerson");} catch (ClassNotFoundException e) {e.printStackTrace();}//通过Object类中的方法实例化secondInstance = new InnerPerson().getClass();//通过类.class实例化thirdInstance = InnerPerson.class;//        System.out.println("类名称:"+firstInstance.getName());//        System.out.println("类名称:"+secondInstance.getName());//        System.out.println("类名称:"+thirdInstance.getName());//获取类实例中的字段并输出//获得public的所有字段数组Field[] fields = firstInstance.getFields();//获取任何权限的所有字段Field[] allFields = firstInstance.getDeclaredFields();System.out.println("---------------所有public字段----------------");for (Field fx : fields) {System.out.println(fx);}System.out.println("---------------所有字段----------------");for (Field fx : allFields) {System.out.println(fx);}//获取方法并输出Method[] m1 = firstInstance.getMethods();Method[] m2 = firstInstance.getDeclaredMethods();System.out.println("---------------所有public方法----------------");for (Method method : m1) {System.out.println(method);}System.out.println("---------------所有方法----------------");for (Method method : m2) {System.out.println(method);}//执行方法并输出System.out.println("---------------使用invoke执行方法----------------");//反射式的,只需要写入方法名,不需要加括号Method m = null;try {Object o = firstInstance.newInstance();try {m = firstInstance.getDeclaredMethod("setName", String.class);try {m.invoke(o, new Object[]{"John"});System.out.println("当前对象为:" + o);} catch (InvocationTargetException e) {e.printStackTrace();}} catch (NoSuchMethodException e) {e.printStackTrace();}} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}

       完整的代码如下所示

package com.example.servlet001;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class ReflectDemo01 {public static void main(String[] args) {//三种不同类实例化方法//第一种实例Class<?> firstInstance = null;//第二种实例Class<?> secondInstance = null;//第三种实例Class<?> thirdInstance = null;//通过类名实例化的方法try {firstInstance = Class.forName("com.example.servlet001.InnerPerson");} catch (ClassNotFoundException e) {e.printStackTrace();}//通过Object类中的方法实例化secondInstance = new InnerPerson().getClass();//通过类.class实例化thirdInstance = InnerPerson.class;
//        System.out.println("类名称:"+firstInstance.getName());
//        System.out.println("类名称:"+secondInstance.getName());
//        System.out.println("类名称:"+thirdInstance.getName());//获取类实例中的字段并输出//获得public的所有字段数组Field[] fields = firstInstance.getFields();//获取任何权限的所有字段Field[] allFields = firstInstance.getDeclaredFields();System.out.println("---------------所有public字段----------------");for (Field fx : fields) {System.out.println(fx);}System.out.println("---------------所有字段----------------");for (Field fx : allFields) {System.out.println(fx);}//获取方法并输出Method[] m1 = firstInstance.getMethods();Method[] m2 = firstInstance.getDeclaredMethods();System.out.println("---------------所有public方法----------------");for (Method method : m1) {System.out.println(method);}System.out.println("---------------所有方法----------------");for (Method method : m2) {System.out.println(method);}//执行方法并输出System.out.println("---------------使用invoke执行方法----------------");//反射式的,只需要写入方法名,不需要加括号Method m = null;try {Object o = firstInstance.newInstance();try {m = firstInstance.getDeclaredMethod("setName", String.class);try {m.invoke(o, new Object[]{"John"});System.out.println("当前对象为:" + o);} catch (InvocationTargetException e) {e.printStackTrace();}} catch (NoSuchMethodException e) {e.printStackTrace();}} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}
}class InnerPerson {private String name;private int age;public String pub;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "reflect.InnerPerson{" +"name='" + name + '\'' +", age=" + age +'}';}
};

        运行该示例后的输出如下图所示

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

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

相关文章

手撸XXL-JOB(四)——远程调用定时任务

Java Socket网络编程 网络编程是Java编程中的重要组成部分&#xff0c;包括服务端和客户端两部分内容。Socket是Java网络编程的基本组件之一&#xff0c;用于在应用程序之间提供双向通信&#xff0c;Socket提供了一种标准的接口&#xff0c;允许应用程序通过网络发送和接收数据…

项目实施方案:多点异地机动车典型系统试验状态可视监控系统

目录 一、需求分析 1.1项目背景 1.2项目概述 二、系统优势 2.1兼容性能力强 2.2接入协议多样 2.3并发能力强 2.3.1 单平台参数 2.3.2 多平台性能参数 2.4 系统稳定性 三、建设目标 3.1安全性 3.2可扩展性 3.3易用性 3.4兼容性 3.5 响应能力 四、系统整体解决方…

Nodejs笔记2

模块化 模块化初体验 模块暴露数据 导入模块 fs 写绝对路径 require写相对路径不会受到影响 ./../不能省略 js 和json文件后缀可以省略 如果存在 命名相同的js和json文件&#xff0c;优先导入js文件 导入文件夹时的情况 require导入模块的基本流程 commonJS模块…

上位机图像处理和嵌入式模块部署(树莓派4b和电源供给)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面&#xff0c;我们说过pc电脑和嵌入式设备&#xff0c;两者都可以实现相同的软件功能。但是和pc相比较&#xff0c;嵌入式设备不仅价格更便宜&a…

24深圳杯C题18页高质量论文+可执行代码+图表

比赛题目的完整版思路可执行代码数据参考论文都会在第一时间更新上传的&#xff0c;大家可以参考我往期的资料&#xff0c;所有的资料数据以及到最后更新的参考论文都是一次付费后续免费的。注意&#xff1a;&#xff08;建议先下单占坑&#xff0c;因为随着后续我们更新资料数…

129.哈希表:有效的字母异位词(力扣)

242. 有效的字母异位词 - 力扣&#xff08;LeetCode&#xff09; 题目描述 代码解决以及思路 这个方法的时间复杂度为O(N)&#xff0c;其中N是字符串的长度&#xff0c;空间复杂度为O(1)&#xff08;因为辅助数组的大小是固定的26&#xff09;。 class Solution { public:bo…

智能终端RK3568主板在智慧公交条形屏项目的应用,支持鸿蒙,支持全国产化

基于AIoT-3568A的智慧公交条形屏&#xff0c;可支持公交线路动态展示&#xff0c;语音到站提醒&#xff0c;减少过乘、漏乘的情况&#xff0c;有效提高了公交服务效率和质量&#xff0c;为乘客提供了更舒适、更安全和更方便的出行体验&#xff0c;为城市的发展增添了新的活力。…

在idea中使用vue

一、安装node.js 1、在node.js官网&#xff08;下载 | Node.js 中文网&#xff09;上下载适合自己电脑版本的node.js压缩包 2、下载完成后进行解压并安装&#xff0c;一定要记住自己的安装路径 一直点击next即可&#xff0c;这部选第一个 3、安装成功后&#xff0c;按住winR输入…

嵌入式科普(16)c语言函数参数的传递方式

目录 一、概述 二、C函数参数 2.1 一张图讲清 2.2 按数据类型分类&#xff1a; 2.2.1 基本数据类型参数&#xff1a; 2.2.2 数组参数&#xff1a; 2.2.3 结构体参数&#xff1a; 2.2.4 指针参数&#xff1a; 2.2.5 函数指针参数&#xff1a; 2.3 按传递方式分类&…

具身触觉社区| “大咖面对面”第一期活动顺利举行

4月27日&#xff0c;由中国人工智能学会认知系统与信息处理专委会组织的“具身触觉社区”第一期“大咖面对面”分享活动顺利举行&#xff0c;我们邀请到了美国麻省理工学院&#xff08;MIT&#xff09;博士、视触觉传感器的奠基人、GelSight指尖传感器发明人李瑞老师为社区带来…

原生小程序开发如何使用 tailwindcss

原生小程序开发如何使用 tailwindcss 原生小程序开发如何使用 tailwindcss 前言什么是 weapp-tailwindcss ?0. 准备环境以及小程序项目1. 安装与配置 tailwindcss 0. 使用包管理器安装 tailwindcss1. 在项目目录下创建 postcss.config.js 并注册 tailwindcss2. 配置 tailwind…

SpringBoot项目的项目部署全过程

一、前端 安装nginx 1.将提前准备好的nginx的安装包上传到Linux中/opt目录下(我用的是Xftp) 2.解压 2.1:在xshell中解压该文件: tar -zxvf nginx-1.20.1.tar.gz 2.2:进入解压后的目录 cd nginx-1.20.1/ 2.3:安装需要的依赖 yum -y install zlib zlib-devel openssl openssl-de…