简述什么是反射以及反射的使用

一.什么是反射

在了解反射之前我们需要先简单来了解一下类加载的过程
在这里插入图片描述

  • 在类加载的过程中,第一步JVM(JAVA虚拟机)将A.class文件读入内存方法区,第二步JVM为A.class创建唯一的Class类的对象,而Class对象是后面访问方法区对应数据的入口

  • 在之前的学习的中,我们通常会用到class关键字,但这里说的Class非彼class,Class在java中是个实际存在的类型,而Class是后面反射需要经常用到的一个类型
    在这里插入图片描述

  • 前面提到在类加载的过程中,会将所有类型生成对应的Class对象,那么反射的应用之一就是可以通过Class来生成任意类的对象

  • 准确来说:

    在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一 个方法;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制

  • 反射的核心API

  • java.long包
    Class类:反射的核心类,可获取类的属性,方法等信息,生成类的实例

  • java.lang.reflect包
    Field类 : 表示类的成员变量,可用来获取和设置类的属性值
    Method类 : 表示类的方法,可用来获取类中的方法信息或者执行方法
    Constructor类 : 表示类的构造方法

二.生成Class对象的三种方式

  • 第一种Class.forName(包名.类型名)//更常用的一种方法,在编译期未知类型,更能体现反射的作用

        //第一种方式Class.forName
        //通过类型包名+类型名来获得需要生成的类型对象,示例生成的是work包下的Student类
        //在反射过程中,有可能会出现一些异常所有需要捕捉一下异常
        Class c1 =Class.forName("work.Student");
  • 第二种调用对象实例方法getClass()
		Student student1=new Student();//先创建类型对象
        Class c2= student.getClass();//通过类型对象.getClass()方法来获取Class类型对象
  • 第三种 类型.class
		Class c3 = Student.class;//通过类型.class来获取Class对象

三.获取相关类的信息

获取属性

  • getFields() - 获取所有可访问的公共字段
  • getDeclaredFields - 所有字段
  • getField(String name) - 返回一个特定的公共字段对象
  • 代码示例
		//第一步获得Class对象
        Class studentClass = Class.forName("work.Student");//通过类型位置+类型名来获得Class对象
        //获取Student类型的相关属性
        Field[] fields = studentClass.getFields();//所有公共字段属性
        Field[] fields1=studentClass.getDeclaredFields();//所有字段
        Field bbb = studentClass.getField("bbb");//获取特定公共字段对象
        //通过增强for来遍历输出所有属性名
        System.out.println("***********所有公共字段************");
        for (Field field : fields) {
            System.out.println(field.getName());
        }
        System.out.println("************所有字段**************");
        for (Field field : fields1) {
            System.out.println(field.getName());
        }
        System.out.println("************特点字段**************");
        System.out.println(bbb.getName());

获取方法

  • getMethods() - 所有的公共方法,包括从超类和超接口继承的声明
  • getDeclaredMethods() - 仅包含本类的所有方法,不包含继承/接口等方法
  • getMethod(String name,Class[] parameterTypes) - 返回一个特点的方法对象
		//第一步获得Class对象
        Class studentClass = Class.forName("work.Student");//通过类型位置+类型名来获得Class对象
        //获取Student类型的相关方法
        
        Method[] methods = studentClass.getMethods();//所有的公共方法,包括从超类和超接口继承的声明
        Method[] declaredMethods = studentClass.getDeclaredMethods();//所有方法,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法
        Method ddd = studentClass.getMethod("ddd",null);//返回一个特点的方法对象,第一个参数:方法名,第二个参数:方法中的参数类型,无参即为null

        //通过增强for来遍历输出所有方法名
        System.out.println("***********所有公共字段************");
        for (Method method : methods) {
            System.out.println(method.getName());
        }
        System.out.println("************所有字段**************");
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
        }
        System.out.println("************bbb**************");
        System.out.println(ddd.getName());

四.反射生成类的实例

需要用到的方法

  • getConstructor()//获得相应类型的构造方法,返回的是Constructor类型对象
  • newInstance()//通过构造方法对象完成类的实例化

代码示例(实例化无参对象)

		//第一步获得Class对象
        Class studentClass = Class.forName("work.Student");
        //第二步获得相应类型的构造方法
        Constructor constructor = studentClass.getConstructor();
        //第三步根据构造方法对象完成类的实例化
        Object o = constructor.newInstance();

代码示例(实例化有参对象)

		//第一步获得Class对象
        Class studentClass = Class.forName("work.Student");//通过类型位置+类型名来获得Class对象
        //第二步获得相应类型的构造方法并设定参数类型
        Constructor constructor=studentClass.getConstructor(int.class,String.class,double.class);
        //第三步根据构造方法对象传入参数完成类的实例化
        Object o = constructor.newInstance(1,"1",1.0);

五.属性的赋值与方法的调用

属性的赋值

		//第一步获得Class对象
        Class studentClass = Class.forName("work.Student");//通过类型位置+类型名来获得Class对象
        //第二步获得相应类型的构造方法并设定参数类型
        Constructor constructor=studentClass.getConstructor(int.class,String.class,double.class);
        //第三步根据构造方法对象传入参数完成类的实例化
        Object o = constructor.newInstance(1,"1",1.0);
        //第四步获得指定属性返回Field类型的对象
        Field aaa = studentClass.getField("aaa");
        //第五步将实例化的对象o中的属性aaa赋值为888
        aaa.set(o,888);

方法的调用

		//第一步获得Class对象
        Class studentClass = Class.forName("work.Student");
        //第二步获得相应类型的构造方法并设定参数类型
        Constructor constructor=studentClass.getConstructor(int.class,String.class,double.class);
        //第三步根据构造方法对象传入参数完成类的实例化
        Object o = constructor.newInstance(1,"1",1.0);
        //第四步获得指定方法并返回Method类型的对象
        Method ddd = studentClass.getMethod("ddd", null);
        //第五步调用invoke方法来操作对象o中的ddd方法,null表示方法无参
        ddd.invoke(o,null);
  • 6
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值