(四)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;

    }



    @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 +
                '}';
    }
};

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

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

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

6. 第K小的和-二分

6.第K小的和 - 蓝桥云课 (lanqiao.cn) #include <bits/stdc.h> #define int long long #define endl \n using namespace std; int n,m,k,an[100005],bm[100005]; int check(int x){int res0;//序列C中<x的数的个数for(int i0;i<n;i){//遍历数组A&#xff0c;对于每…

【Linux】如何在Linux中配置自己的环境变量?

文章目录 配置环境变量方法一&#xff1a;【>>】使用追加重定向方法二&#xff1a;使用【export PATH$PATH:/路径】(推荐) 配置环境变量 那要怎么去将一个系统路径添加到【环境变量】中呢 方法一&#xff1a;【>>】使用追加重定向 &#x1f6a9;这里一定要主要覆盖…

mongodb备份还原指南

MongoDB 提供的命令行实用程序mongodump和mongorestore创建备份和恢复数据的过程。 一、数据备份 mongorestore和mongodump实用程序可处理BSON数据转储&#xff0c;对于创建小型部署的备份非常有用。要实现弹性且无中断的备份&#xff0c;请将文件系统快照或区块级磁盘快照与…

Git 的原理与使用(中)

Git 的原理与使用&#xff08;上&#xff09;中介绍了Git初识&#xff0c;Git的安装与初始化以及工作区、暂存区、版本库相关的概念与操作&#xff0c;本文接着上篇的内容&#xff0c;继续深入介绍Git在的分支管理与远程操作方面的应用。 目录 五、分支管理 1.理解分支 2.创…

免费Premiere模板,几何图形元素动画视频幻灯片模板素材下载

Premiere Pro模板&#xff0c;几何图形元素动画视频幻灯片模板 &#xff0c;组织良好&#xff0c;易于自定义。包括PDF教程。 项目特点&#xff1a; 使用Adobe Premiere Pro 2021及以上版本。 19201080全高清。 不需要插件。 包括帮助视频。 免费下载&#xff1a;https://prmu…

Java毕业设计 基于SpringBoot vue药店管理系统

Java毕业设计 基于SpringBoot vue药店管理系统 SpringBoot 药店管理系统 功能介绍 员工 登录 个人中心 修改密码 个人信息 查看供应商信息 查看药品 查看进货 查看销售 管理员 登录 个人中心 修改密码 个人信息 供应商类型管理 供应商信用等级类型管理 药品类型管理 供应商信…

【Web后端】MVC模式

1、简介 MVC模式&#xff0c;全称Model-View-Controller&#xff08;模型-视图-控制器&#xff09;模式&#xff0c;是一种软件设计典范&#xff0c;它将应用程序的用户界面&#xff08;视图&#xff09;和业务逻辑&#xff08;模型&#xff09;分离&#xff0c;同时提供了一个…

langchain_community FAISS保存与加载faiss index

参考: https://github.com/langchain-ai/langchain/issues/18285 https://api.python.langchain.com/en/latest/vectorstores/langchain_community.vectorstores.faiss.FAISS.html#langchain_community.vectorstores.faiss.FAISS 1、保存save_local import pandas as pd ##…

(深度估计学习)Win11复现DepthFM

目录 1. 系统配置2. 拉取代码&#xff0c;配置环境3.开始深度预测4.运行结果 论文链接&#xff1a;https://depthfm.github.io/ 讲解链接&#xff1a;https://www.php.cn/faq/734404.html 1. 系统配置 本人系统&#xff1a;Win11 CUDA12.2 python3.11.5 这里附上几个CUDA安装链…

iOS——runtime

什么是runtime 我们都知道&#xff0c;将源代码转换为可执行的程序&#xff0c;通常要经过三个步骤&#xff1a;编译、链接、运行。 C 语言 作为一门静态类语言&#xff0c;在编译阶段就已经确定了所有变量的数据类型&#xff0c;同时也确定好了要调用的函数&#xff0c;以及函…

算法提高之加成序列

算法提高之加成序列 核心思想&#xff1a;迭代加深 dfs 从上往下逐渐增大depth 这样下面没有用的方案就不用遍历了 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 110;int n;int path[N];//当前求哪个位置…

如何去掉图片背景改成透明的?一键图片去底色工具推荐

如何去掉图片背景改成透明的&#xff1f;在很多比较特殊的场景中&#xff0c;我们需要把图片背景底色去除后再进行使用&#xff0c;比如一些商品展示图或者是网页设计中的一些logo图标&#xff0c;专业人士会直接选择使用ps来处理&#xff0c;但是也有许多新手小白不知道怎么去…

steam商店打不开、steam商店错误代码-118的解决方法

现在steam已经开始了&#xff0c;有很多好玩的游戏都在这段时间相继打折&#xff0c;虽然游戏众多&#xff0c;但是不是所有人都能把这些游戏都买下来&#xff0c;有一些小伙伴喜欢的游戏苦于没有足够的资本去购买&#xff0c;steam会以各种名义举办特惠活动吸引玩家们&#xf…

如何实现微信扫码登录windows操作系统

将微信扫码登录功能集成到Windows操作系统级别的身份认证系统&#xff08;如你所提到的“安当ASP身份认证系统”&#xff09;是一个复杂的任务&#xff0c;因为Windows操作系统本身并不直接支持第三方应用&#xff08;如微信&#xff09;作为登录凭证。然而&#xff0c;你可以通…

Docker 部署 Nginx 实现一个极简的 负载均衡

背景: Nginx是异步框架的网页服务器&#xff0c;其常用作反向代理(负载均衡器)。在一般的小项目中, 服务器不多, 如果不考虑使用服务注册与发现, 使用Nginx 可以容易实现负载均衡。 在特此写一个快速入门 Nginx 的技术贴, 使用 Docker 部署 Nginx, 实现一个极简的加权轮询负载均…

obsidian 外观设置解毒

前言 一入obsidian深似海&#xff0c;外观设置也是五花八门&#xff0c;仿佛回到读书时期折腾桌面一样。 我对比了AnuPpuccin、minimal和其他的一些外观主题&#xff0c;设置都太复杂了&#xff0c;尤其是需要调整CSS文件&#xff0c;最后发现一款&#xff0c;非常好用&#…

OpenHarmony 3.1 Release实战开发 + Linux 原厂内核Launcher起不来问题分析报告

1、关键字 Launcher 无法启动&#xff1b;原厂内核&#xff1b;Access Token ID&#xff1b; 2、问题描述 芯片&#xff1a;rk3566&#xff1b;rk3399 内核版本&#xff1a;Linux 4.19&#xff0c;是 RK 芯片原厂发布的 rk356x 4.19 稳定版内核 OH 版本&#xff1a;OpenHa…

接口、会话控制

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