天天看点

浅谈反射机制

一、反射的概念

反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。

这句话就是JDK8明确定义的反射机制的概念

其实真的不好理解 ,我一直理解的反射是:

反射就是在程序运行过程中,根据字节码文件获得类的信息,根据字节码文件创建对象、访问字段、调用方法的技术。

我觉得这样比较好理解。

那么反射依赖于class对象,那么我们怎么创建class对象呢?简单说就是获得类的字节码文件

获取类的字节码文件的方式有三种:

Class class = Class.forName(绝对类路径);

Class class = 类名.class

Class class = 对象名.getclass();

通过以上的三种方式任意一种就可以获取到我们的类的 字节码文件

那么如果字节码文件创建对象呢?

newInstance() 字节码文件调用newInstance()方法可以创建字节码文件的对应类对象。

实际上有了对象就可以访问对象里的构造方法和私有属性。

但是如果只是这样反射的技术采用一点点呀,实际开发中,我们都知道实体类中方法属性和构造方法都喜欢定义为private私有的,这种保护机制也让我们一些场景想修改属性值调用私有方法时带来了不便,那么反射技术就可以帮助我们解决。

例如:

public class Father {
    private String name;
}

public class student extends Father{
    private age;
    private String sex;

    private String sayHello(String name){
        return "hello:" + name;
    }

    private  String sayHello(){
        return "hello";

    }
}
           

Test测试:

public class Test1 {
    public static void main(String[] args) throws Exception {
        student stu = new student();
        Class classFile = stu.getClass();

        //2.在Student.class定位一个名字叫做"sex"属性
        Field field=classFile.getDeclaredField("sex");
        //设置访问权限
        field.setAccessible(true);
        field.set(stu,"man");
        System.out.println(field.getName()+"="+field.get(stu));
        System.out.println(field.getType().getName());

        Class classArray[] = {java.lang.String.class};


        Method method = classFile.getDeclaredMethod("sayHello", classArray);
        method.setAccessible(true);
        String value = (String) method.invoke(stu, "mike");
        System.out.println(value);
    }
}
           

显示Student类中属性name和sex都是私有属性,以及构造方法私有化,那么这种private修饰的方法和属性除了自身类对象其它都是不能访问和设值的,这时候如果业务需要我们可能需要创建类对象才行,那么如果使用反射技术大大简化了这种难度。

反射技术使用非常多,Spring框架大量使用反射技术、Mybatis数据源映射,如果将SQL语句中的数据源和Java对象进行转化底层使用的就是反射机制,通过调用 Method.invoke() 调用get / set方法完成对象和数据源之间的映射关系。

可以说越学到深入,反射的理解越深。我们通常说一个程序员技术好不好,很大一种程度上反映发射有多牛