(四)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.mzph.cn/bicheng/12412.shtml

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

相关文章

python的标准数据类型

四、标准数据类型 1、为什么编程语言中要有类型 类型有以下几个重要角色&#xff1a; 对机器而言&#xff0c;类型描述了内存中的电荷是怎么解释的。 对编译器或者解释器而言&#xff0c;类型可以协助确保上面那些电荷、字节在程序的运行中始终如一地被理解。 对程序员而言…

基于大模型训练的数字识别

创作原因 现在写电赛题&#xff0c;题目有识别数字的要求。但使用设备openmv使用模板匹配的算法帧率很低&#xff0c;且识别效果不是很好&#xff0c;于是我们就想到了利用神经网络训练模型来识别数字 正文部分 内容介绍 本文内容是基于openmv使用Edge Impulse训练大模型。…

服务攻防——应用协议ssh,rsync,proftpd,openssh,libssh

1.口令猜解 ftp-拿来文件传输的 rdp-windows远程连接 3389 ssh-linux远程连接 工具hydra 口令 1.windows 这就爆破成功了&#xff0c;现在&#xff0c;我们就可以ftp爆破&#xff0c;爆破出ftp的密码 爆破出来后 访问 2.ssh Rsync&#xff08;配置不当&#xff0c;未授权…

Gooxi发布最新AI服务器:加速生成式AI落地 更懂AI

近日&#xff0c;Gooxi发布最新训推一体AI服务器&#xff0c;以大容量内存和灵活的高速互连选项满足各种AI应用场景&#xff0c;最大可能支持扩展插槽&#xff0c;从而大幅提升智能算力性能&#xff0c;以最优的性能和成本为企业的模型训练推理落地应用提供更好的通用算力。 AI…

主从Reactor服务器

目录&#xff1a; 目录&#xff1a; 目标&#xff1a; 本文讲解思路&#xff1a; 各模块的功能以及代码&#xff1a; 1.服务器相关模块&#xff1a;服务器模块的功能是对所有的连接以及线程进⾏管理 2.协议相关模块&#xff1a;协议模块是对当前的Reactor模型服务器提供应…

【HarmonyOS】Stage 模型 - 应用配置文件

如图所示&#xff1a; Stage 模型应用配置文件主要有两类&#xff1a; 全局配置文件。放在 AppScope 目录下&#xff0c;app.json5。用来配置应用全局的信息。模块配置文件&#xff0c;放在每个模块里&#xff0c;module.json5。用来配置模块的信息。 一、全局配置文件 示…

LeetCode1657确定两个字符串是否接近

题目描述 如果可以使用以下操作从一个字符串得到另一个字符串&#xff0c;则认为两个字符串 接近 &#xff1a; 操作 1&#xff1a;交换任意两个 现有 字符。例如&#xff0c;abcde -> aecdb操作 2&#xff1a;将一个 现有 字符的每次出现转换为另一个 现有 字符&#xff0…

【数据可视化01】matplotlib实例3之数据统计

目录 一、引言二、实例介绍1.百分位数为横条形图2.箱线图定制化3.带有自定义填充颜色的箱线图4.箱线图5.箱线图和小提琴图6.二维数据集的置信椭圆 一、引言 matplotlib库 可以用来创建各种静态、动态、交互式的图形&#xff0c;并广泛应用于数据分析和数据可视化领域。 二、实…

贷款中介CRM管理系统解决方案

一、贷款中介行业背景介绍 随着贷款中介行业的快速发展&#xff0c;贷款中介业务逐渐成为企业和个人融资的重要渠道。然而&#xff0c;贷款中介行业存在信息不对称、风险控制不力等难题。给金融稳定带来潜在风险。 二、方案目的和意义 鑫鹿贷款中介系统解决方案旨在规范贷款中…

Elasticsearch查看集群信息,设置ES密码,Kibana部署

Elasticsearch查看集群信息&#xff0c;设置ES密码&#xff0c;Kibana部署 查看集群信息查看节点信息查看集群健康状态查看分片信息查看其他集群信息 Kibana部署安装设置ES密码 查看集群信息 查看节点信息 curl http://127.0.0.1:9200/_cat/nodes?v 参数说明&#xff1a; ip…

研究生学习---找工作

规划 研一~研二上学期完成小论文&#xff0c;实习&#xff0c;秋招 竞赛&#xff1a;kaggle&#xff1f; 面试题一般简单且为原题&#xff0c;笔试题目很难&#xff0c;不会出原题 项目 找工作软件

SwiftUI中三大渐变色的介绍

在SwiftUI中&#xff0c;渐变色是一种常用的视觉效果&#xff0c;用于创建平滑过渡的颜色变化。通过使用渐变色&#xff0c;我们可以实现丰富多彩的界面设计&#xff0c;增强用户体验。 1. 渐变色的种类和用途 种类&#xff1a; 线性渐变&#xff08;Linear Gradient&#x…

【时隙ALOHA,CSMA(载波侦听多路访问)carrier sense mltiple access,无线局域网: CSMA/CA】

文章目录 时隙ALOHA时隙ALOHA的效率( Efficiency )纯ALOHA(非时隙)----效率低CSMA(载波侦听多路访问)carrier sense mltiple accessCSMA冲突CSMA/CD(冲突检测)边说边听&#xff08;提高了信道利用率&#xff09;以太网就是用的这个无线局域网: CSMA/CA无线局域网中的 MAC&#…

Transformer+Classification学习笔记

论文名称&#xff1a;An Image is Worth 16x16 Words:Transformers for Image Recognition at Scale [2112.11010] MPViT: Multi-Path Vision Transformer for Dense Prediction (arxiv.org) 参考博客与视频&#xff1a; Vision Transformer 超详细解读 (原理分析代码解读) …

2024年了,Covid19怎么发?PANoptosis程序性死亡,抓紧上车!

说在前面 大家众所周知的新冠&#xff0c;其实早在19年末&#xff0c;20年初的时候很多人都抓住了这个热点发到了好文章&#xff0c;Covid-19&#xff0c;这玩意可以做到让一个期刊从2分飙升到20分&#xff0c;且非预警期刊&#xff0c;不过现在退火了&#xff0c;今年是12.7分…

数据结构(十四)----排序算法(1)

目录 一.排序的基本概念 二.插入排序 1.直接插入排序 2.折半插入排序 三.希尔排序&#xff08;Shell Sort&#xff09; 四.交换排序 1.冒泡排序 2.快速排序 快速排序算法的效率&#xff1a; 快速排序算法的稳定性&#xff1a; 这一篇博客的重点主要是快速排序&#x…

2024小红书电商实战营,养号打造IP/选爆品/开店铺/爆款笔记/等等(24节)

我们非常荣幸地为大家带来2024小红书电商实战营的第一期&#xff0c;在这里我们将带领大家一起深入学习如何利用小红书平台&#xff0c;实现个人品牌的发展和商业利益的增长。 首先&#xff0c;我们将讨论养号的重要性以及如何打造个人品牌。无论是建立自己的受众群体还是提高…

微信小程序知识点归纳(一)

前言&#xff1a;适用于有一定基础的前端开发同学&#xff0c;完成从网页开发到小程序开发的知识转换。 先立框架&#xff0c;后砌墙壁 回顾&#xff1a;了解微信小程序开发流程-CSDN博客 初始页面结构&#xff0c;三部分pages、utils、配置&#xff0c;分别存放页面、工具类…

【解决】Unity Build 应用程序运行即崩溃问题

开发平台&#xff1a;Unity 2021.3.7f1c1   一、问题描述 编辑器 Build 工程结束&#xff0c;但控制台 未显示 Build completed with a result of Succeeded [时间长度] 信息。该情况下打包流程正常&#xff0c;但应用程序包打开即崩溃。   二、问题测试记录 测试1&#xf…

百面算法工程师 | 传统图像处理——OpenCV

本文给大家带来的百面算法工程师是传统图像处理的面试总结&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们将总结一些几何变换和图像平滑处理&#xff0c;并提供参考的回答及其理论基础&#…