Java反射机制

一、 何为反射机制
简单来说,反射机制指的是程序在运行过程中能够获取自身的信息。反射机制在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个属性和方法(包括私有的,是不是好可怕,没有隐私了。。);这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。
二、 反射机制主要的功能
在运行时判断一个对象所属的类;
在运行时获取任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
生成动态代理;

在继续往下面深入之前,咱们先来简单说一下要想使用一个类需要完成的三个步骤:
    加载(根据字节码创建一个Class对象);
    链接(验证类中的字节码,为静态域分配存储空间);
    初始化(如果该类有超类,则先对超类进行初始化,执行静态初始化器和静态初始块)

对于每一个类,在内存中只有唯一的一个Class对象,也就是每一个类的class文件信息在内存中对应唯一的一个Class对象的引用。因此,我们只要能够获得对应类的Class引用。则关于类的所有信息都能知道不是吗?因为类的所有信息都是可以通过class文件获得的。

获取一个类的Class对象的三种方式:(假设有一个Person类,它的一个实例对象为person,这个类所在的包为:com.jcw.test)

  • 通过实例对象获得:Class c1 = person.getClass();
  • 通过Class类的静态方法-forName()获得:Class c2 = Class.forName(“com.jcw.test.Person”);
  • 通过一个类的默认属性获得-class:Class c3 = Person.class

三、 利用反射机制获得的信息
    一句话,类中有什么信息,它就可以获得什么信息,不过需要首先知道类的名字,并且能够通过相应的类加载器找到对应的类。

获取构造函数的方法
Constructor getConstructor(Class… parameterTypes) //根据指定的参数获取对应的public构造器
Constructor[] getConstructors()//获取所有的public构造器
Constructor getDeclaredConstructor(Class… parameterTypes)//根据指定参数获取public或非public构造器
Constructor[] getDeclaredConstructors()//获取所有的构造器

获得类方法的方法
Method getMethod(String name, Class… parameterTypes)//根据方法名和给定的参数获得public方法
Method[] getMethods()//获取所有的public方法
Method getDeclaredMethod(String name, Class… parameterTypes)//根据方法名和指定的参数获得方法
Method[] getDeclaredMethods() //获得所有的方法

获得类中属性的方法
Field getField(String name)//根据变量名得到相应的public变量
Field[] getFields()//获得所有的public方法
Field getDeclaredField(String name)//根据方法名获得变量
Field[] getDeclaredFields()//获得所有的变量

四、用反射机制来做一些事情

首先定义一个Person类:

package com.jcw.reflect;

public class Person {
    public String name = "defaultName";
    private String age = "defaultAge";

    //无参构造器
    public Person(){}

    //有参构造器
    public Person(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public void say() {
        System.out.println("我上课在说话,你敢吗?");
    }

    private void run() {
        System.out.println("放学了,我跑了出去");
    }

}

在Person类中,有一个public变量name,一个private变量age,一个public方法say,一个private方法run。正常情况下,变量age和方法run()在外部是访问不到的,也是不能够修改的。下面通过测试看咱们怎样访问到这些按理是访问不到的private成员和方法。

定义一个测试类

package com.jcw.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class PersonTest {
    public static void main(String[] args) throws  Exception {
        /**
         *最原始的实例化一个person对象
         */
        Person person = new Person();
        person.say();
        //我想调用Person类中的私有方法run(),但是访问不了
        //person.run();
        System.out.println("person.name: " + person.name);
        //我想访问Person类的中私有成员变量age,但是访问不了
        //System.out.println(person.age);

        /**
         * 通过反射机制来获得构造器的方式来获取一个Person的实例
         */
        Class<Person> class1 = Person.class;
        Constructor<Person> constructor = class1.getConstructor();
        constructor.setAccessible(false);
        Person person1 = constructor.newInstance();
        //我想访问私有run()方法,看下面反射机制如何访问。
        Method method1 = class1.getDeclaredMethod("run");
        //这一句话保证了私有方法也能够被调用
        method1.setAccessible(true);
        //这一步将会成功地调用run方法
        method1.invoke(person1);
        System.out.println("person1.name: " + person1.name);
        //我想访问私有的成员变量age
        Field field1 = class1.getDeclaredField("age");
        //这一句话保证了这个私有成员变量也能够被访问
        field1.setAccessible(true);
        System.out.println("person1.age: " + field1.get(person1));
        //修改age变量的值
        field1.set(person1,"我是修改过的值");
        System.out.println("person1.age: " + field1.get(person1));



    }
}

Output:
这里写图片描述

根据分析,我们成功访问到了private的成员和方法,并且还成功修改了age的值。其中一句话比较重要,就是调用setAccessible(true)。

总结:上述就是简单的说明了一下反射机制的作用,可以看到通过反射,我们能够访问到正常访问不到的东西,而且上面的代码可以整理为一个模板,只能传入对应的类名,方法名,成员变量名,就能够访问想访问的东西。其中反射机制在一些框架(比如SSH,mybatis等)使用的比较多,像动态代理,AOP等都用到了反射机制。大家可以了解下这个东西,以后在学框架,动态代理等知识时,能够极大减轻学习的负担。

有说不对的地方,请各位指正。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值