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

news2024/11/18 19:44:07

        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;

    }



    @Override

    public 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;
    }

    @Override
    public String toString() {
        return "reflect.InnerPerson{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
};

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

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

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

相关文章

服务攻防——应用协议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;未授权…

刷题之找到字符串所有字母异位词

找到字符串所有字母异位词 滑动窗口。滑动窗口大小为待比较数组的大小。 class Solution { public:vector<int> findAnagrams(string s, string p) {//滑动窗口vector<int>result;if(s.size()<p.size())return result;vector<int>pnum(26,0);//记录p的字…

LQ杯当时的WP

RC4 32位程序用IDA打开看看 进行反汇编 RC4提示&#xff0c;就是一个加密 在sub_401005函数中找到输出的变量&#xff0c;并且立下断点 动调 Packet 字符串搜索flag 看到是给192.168.11.128发送了cat flag的命令 看到它回传 Base64加密了 解一下密码就可以 CC 密码这…

DELL服务器配置ILO(idrac)地址、修改管理员密码

服务器型号&#xff1a;DELL PowerEdge R630 1、重启服务器选择F2进入BIOS 2、重启服务器选择F2进入BIOS 3、选择“Network” 4、配置iDRAC的IP&#xff0c;掩码网关&#xff0c;DNS等信息 5、Esc返回&#xff0c;下滑选择“User Configuration” 6、配置iDRAC的用户名密码以及…

【Java基础】我不允许还有人搞不懂lambda表达式!!!

λ希腊字母表中排序第十一位的字母避免匿名内部类定义过多&#xff0c;使得代码更加简洁其实质属于函数式编程的概念 (params)->expression[表达式] (params)->statement[语句] (params)->{statements}lambda表达式推导过程&#xff1a; 创建一个类&#xff0c;重写接…

HTML特殊字符

特殊字符 有特殊含义的字符成为字符实体 对于有特殊含义的字符,需要通过转移字符来表示 <span> <br><a href"http://www.atguigu.com">我 爱 前端</a> <br>&amp;amp; 效果

前端CSS3基础1(新增长度单位,盒子模型,背景,边框,文本属性,渐变,字体,2D变换,3D变换)

前端CSS3基础1&#xff08;新增长度单位&#xff0c;盒子模型&#xff0c;背景&#xff0c;边框&#xff0c;文本属性&#xff0c;渐变&#xff0c;字体&#xff0c;2D变换&#xff0c;3D变换&#xff09; CSS3 新增长度单位CSS3 新增盒子模型相关属性box-sizing怪异盒模型box-…

10G UDP协议栈 IP层设计-(6)IP TX模块

一、模块功能 1、上层数据封装IP报文头部 2、计算首部校验和 二、首部校验和计算方法 在发送方&#xff0c;先把IP数据报首部划分为许多16位字的序列&#xff0c;并把检验和字段置零。用反码算术运算把所有16位字相加后&#xff0c;将得到的和的反码写入检验和字段。接收方收…

分布式系统的一致性与共识算法(二)

Consitency 背景 如买最后一张车票&#xff0c;两个售票处分别通过某种方式确认过这张票的存在。这时&#xff0c;两家售票处几乎同时分别来了一个乘客要买这张票&#xff0c;从各自"观察"看来&#xff0c;自己一方的乘客都是先到的&#xff0c;这种情况下&#xf…

【Shell脚本】Shell编程之数组

目录 一.数组 1.基本概念 2.定义数组的方法 2.1.方法一 2.2.方法二 2.3.方法三 2.4.方法四 2.5.查看数组长度 2.6.查看数组元素下标 3.数组分片 4.数组字符替换 4.1.临时替换 4.2.永久替换 5.数组删除 5.1.删除某个下标 5.2.删除整组 6.数组遍历和重新定义 7…

sql操作、发送http请求和邮件发送 全栈开发之路——后端篇(2)

全栈开发一条龙——前端篇 第一篇&#xff1a;框架确定、ide设置与项目创建 第二篇&#xff1a;介绍项目文件意义、组件结构与导入以及setup的引入。 第三篇&#xff1a;setup语法&#xff0c;设置响应式数据。 第四篇&#xff1a;数据绑定、计算属性和watch监视 第五篇 : 组件…

国内好用的测试用例管理工具有哪些?

目前市面上的测试用例管理工具有很多&#xff0c;但由于针对的项目、领域、目标用户&#xff0c;功能也并不一致&#xff0c;所以选择一款适合的测试管理平台并不轻松。做好这件事&#xff0c;首先要需求明确你用测试管理工具干什么&#xff1f;最终想要达到什么目标&#xff1…

基于UnetPlusPlus(Unet++)实现的医学图像分割

1、前言 unetPlusPlus 在unet 的基础上增添了密集连接的结构&#xff0c;有点像densenet网络 因为这种密集连接&#xff0c;unet可以实现剪枝的轻量化操作。由于本人的没有接触过这种剪枝、蒸馏之类的轻量化方法&#xff0c;所以不多赘述 本章仅仅根据unet模型实现医学图像分…

西门子博途WINCC精致触摸屏配方实用一例

我们现场有一台设备&#xff0c;是用来锯切钢坯的&#xff0c;里面有几个重要的参数&#xff0c;一开始投产的时候厂家没有做配方功能&#xff0c;需要操作人员每次换钢坯就需要手动计算然后输入&#xff0c;后来有时间我就做了个这个定尺管理的功能&#xff0c;方便了操作人员…

汇昌联信电商:拼多多网店好做吗?

在电子商务的海洋中&#xff0c;拼多多以其独特的团购模式和亲民策略迅速崛起&#xff0c;吸引了大批消费者和商家的目光。对于“拼多多网店好做吗?”这个问题&#xff0c;答案并非简单的是与否&#xff0c;而是需要从多个维度进行深入分析。 一、市场定位与竞争环境 拼多多定…

华为开源自研AI框架昇思MindSpore应用案例:在ResNet-50网络上应用二阶优化实践

常见的优化算法可分为一阶优化算法和二阶优化算法。经典的一阶优化算法如SGD等&#xff0c;计算量小、计算速度快&#xff0c;但是收敛的速度慢&#xff0c;所需的迭代次数多。而二阶优化算法使用目标函数的二阶导数来加速收敛&#xff0c;能更快地收敛到模型最优值&#xff0c…

TCP的滑动窗口机制和流量控制

目录 滑动窗口 流量控制 拥塞控制 滑动窗口 TCP除了保证可靠性之外&#xff0c;也希望能够尽可能高效的完成数据传输。滑动窗口就是一种提高效率的机制。以下是不引入滑动窗口的数据传输过程&#xff1a; 可以看到&#xff0c;主机A这边每次收到一个ACK才发送下一个数据。这…

接口、会话控制

文章目录 接口介绍RESTful APIjson-server接口测试工具apipost公共参数和文档功能 会话控制cookie介绍和使用运行流程浏览器中操作Cookieexpress中cookie操作 Sessionsession运行流程&#xff1a;session中间件配置session 和 cookie 的区别CSRF跨站请求伪造 tokenJWT介绍与演示…

数据新探:用Python挖掘互联网的隐藏宝藏

Hello&#xff0c;我是你们的阿佑&#xff0c;今天给大家上的菜是——数据存储&#xff01;听起来枯燥无味&#xff1f;错了&#xff01;阿佑将带你重新认识数据存储的艺术。就像为珍贵的艺术品寻找完美的展览馆&#xff0c;为你的数据选择合适的存储方式同样重要&#xff01; …