Java 反射机制原理及过程

反射

官方的概念是:Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。

还有一种说法就是:反射就是把一个类的各个组成部分(成员方法,成员变量和构造方法等)分别各自封装为一个对象。

个人理解:反射就是虚拟机把.class文件加载到内存中,于此同时,会帮.class文件生成一个Class对象,而这个Class对象把.class文件的所有成员方法,成员变量和构造方法等封装成一个对象作为成员变量,然后通过Class对象获取对应的成员变量(对象),然后操作这些对象,来操作类的成员等。
(补充一点:在JVM看来,所有的方法或变量,都是普通的方法或普通变量,万物皆普通。)

在这里插入图片描述

反射的出来的Class对象

Class对象能操作类的那些东西呢?Class对象能操作方法对象(Method),变量对象(Field),构造函数对象(constructor)。

获取Class对象的方法:

  • Class.forName(“类的全路径名”):全路径名,即src目录下一级目录开始
  • 类名.class
  • 类对象.getClass()

1、Class对象操作方法对象(Method)的一些方法

  • Method getMethod(String methodName):获取public修饰的一个方法,返回方法的对象
  • Method [ ] getMethods():获取所有public修饰的方法,返回一个数组,存储所有方法对象
  • Method getDeclareMethod(String methodName):获取任何修饰符修饰的一个方法,返回方法对象
  • Method [ ] getDeclareMethod():获取任何修饰符修饰的所有方法,返回数组,存储所有方法对象

2、Class对象操作变量对象(Field)的一些方法

  • Field getField(String valueName):获取public修饰的一个变量,返回变量对象
  • Field [ ] getFields():获取public修饰的所有变量,返回数组,存储所有变量对象
  • Field getDeclareField(String valueName):获取任何修饰符修饰的一个变量,返回变量对象
  • Field [ ] getDeclareFields():获取任何修饰符修饰的所有变量,返回数组,存储所有变量对象

3、Class对象操作构造函数(Constructor)的一些方法

  • Constructor getConstructor(String constructorName):获取public修饰的一个构造函数,返回构造函数的对象
  • Constructor[] getConstructors(String constructorName):获取public修饰的所有构造函数,返回一个数组,存储构造函数对象
    • Constructor getDeclareConstructor(String constructorName):获取public修饰的一个构造函数,返回构造函数的对象
  • Constructor[] getDeclareConstructors(String constructorName):获取public修饰的所有构造函数,返回一个数组,存储构造函数对象

反射操作类

获取到封装好的类成员等对象之后,就可以获取他们,改变他们了。

1、操作变量(变量对象下的一些操作)

  • length:变量对象的总数。
  • int getModifiers():获取变量的修饰符,返回一个int类型的。需要通过Modifiers.toString(int num)转换成字符串类型。Modifier.toString(c.getModifiers())
    -String getType():返回类型的名称(如果是引用类型,返回全路径名)。简化名称需要用getSimpleName()。f.getType().getSimpleName()
  • String getName():返回变量名。
  • Object get(Object o):返回变量值。传入的是该类的实例化对象。可以使newInstance得到的对象,也可以是new该类得到的对象。

2、操作方法(方法对象下的一些操作)

  • length:方法对象的总数。
  • int getModifiers():获取方法的修饰符,返回一个int类型的。需要通过Modifiers.toString(int num)转换成字符串类型。Modifier.toString(c.getModifiers())
  • String getReturnType():返回方法的返回类型。
  • String getName():返回方法的名称。简化名称需要用getSimpleName()。f.getType().getSimpleName()
  • int getParameterCount():返回方法参数的个数。
  • Class [ ] getParameterTypes():返回方法的所有参数类型,封装为Class对象。通过遍历,获取每个参数的类型。

3、操作构造函数(构造函数对象下的一些操作)

  • int getModifiers():获取构造函数的修饰符,返回一个int类型的。需要通过Modifiers.toString(int num)转换成字符串类型。Modifier.toString(c.getModifiers())
  • String getName():获取构造函数的名字。简化名称需要用getSimpleName()。f.getType().getSimpleName()
  • int getParameterCount():返回构造函数参数的个数。
  • Class [ ] getParameterTypes():返回构造函数的所有参数类型,封装为Class对象。通过遍历,获取每个参数的类型。
  • newInstance(Object…param):创建一个反射的类的对象。如果是无参构造,也可以使用Class对象中的newInstance来创建一个类对象。

4、操作类本身

  • int getModifiers():获取构造函数的修饰符,返回一个int类型的。需要通过Modifiers.toString(int num)转换成字符串类型。Modifier.toString(c.getModifiers())
  • String getName():获取类名称。简化名称需要用getSimpleName()。f.getType().getSimpleName()

代码

package cn.reflectDemo;

import java.lang.reflect.*;

public class reflect {
    /**
     * 反射机制 反编译成java文件 获取类的所有属性和方法 包括静态的
     * @author 一只搬砖的码蚁
     * @date 2020/9/14 13:31
     */
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
        test1();
    }
    //第一种获取反射的方法Class.forName
    public static void test1() throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //Class.forName 获取Class对象
        Class c = Class.forName("cn.reflectDemo.User");
        //获取所有属性
        Field[] fs=c.getDeclaredFields();
        //实例化
        Object o = c.newInstance();

        //获取类的修饰符
        System.out.println("类的修饰符:"+Modifier.toString(c.getModifiers()));
        System.out.println("类的名称:"+c.getSimpleName());
        System.out.println("属性个数:"+fs.length);
//        System.out.println(fs);

      //显示所有属性名和属性值 以及修饰符
        for (Field f : fs) {
            f.setAccessible(true);
            System.out.println("-----------------------------");
            System.out.println("变量修饰符:"+Modifier.toString(f.getModifiers()));
            System.out.println("变量的类型:"+f.getType().getSimpleName());
            System.out.println("变量名:"+f.getName());
            System.out.println("变量值:"+f.get(o));
        }

        //获取所有方法
        Method[] declaredMethods = c.getDeclaredMethods();
        System.out.println("------------------------------------");
        System.out.println("方法个数:"+declaredMethods.length);
        for (Method declaredMethod : declaredMethods) {
            declaredMethod.setAccessible(true);
            System.out.println("-----------------------------");
            System.out.println("方法修饰符:"+Modifier.toString(declaredMethod.getModifiers()));
            System.out.println("方法返回类型:"+declaredMethod.getReturnType());
            System.out.println("方法名:"+declaredMethod.getName());
            Class[] params = declaredMethod.getParameterTypes();
            Parameter[] parameters = declaredMethod.getParameters();
            for (Class param : params) {
                System.out.println("方法参数类型:"+param);
            }
            System.out.println("方法参数个数:"+declaredMethod.getParameterCount());
           // System.out.println(declaredMethod.invoke(o));
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

搬砖的码蚁

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

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

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

打赏作者

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

抵扣说明:

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

余额充值