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

(一)Spring教程——Spring框架简介 

(二)Spring教程——Spring框架特点

(三)Spring教程——依赖注入与控制反转

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

(五)Spring教程——Spring IoC容器(上)

(六)Spring教程——Spring IoC容器(中)

(七)Spring教程——Spring IoC容器(下)

前言        

        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来调用方法,设置类的某个属性。

1.创建InnerPerson类

        首先我们创建一个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 +

                '}';

    }

};

        该类 提供了设置Name或获取Name的方法,设置Age或者获取Age的方法,并重写了类的toString方法。

2.打印三种方式实现的类名称

       然后我们创建一个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());

    }

}

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

        可以看到三种方式生成的InnerPerson类名称都是一样的。 

3.打印字段方法并使用invoke执行方法

        继续修改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 +
                '}';
    }
};

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

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jerry95270628

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值