反射-概述

整理回顾

概述

  • 反射: 框架设计的灵魂
  1. 框架: 半成品软件,可以在框架的基础上进行软件开发,简化编码
  2. 反射: 将类的各个组成部分封装为其他对象,这就是反射机制
  • 反射的好处
  1. 可以在程序运行过程中,操作这些对象。
  2. 可以解耦,提高程序的可扩展性。
    在这里插入图片描述

获取Class对象的方式:

  1. Class.forName("全类名") : 将字节码文件加载进内存,返回Class对象。
    多用于配置文件,将类名定义在配置文件中。 读取文件,加载类。
  2. 类名.class : 通过类名的属性class获取
    多用于参数的传递
  3. 对象.getClass() : getClass() 方法在Object类中定义着。
    多用于对象的获取字节码的方式。
演示:
   // 获取Class对象的三种方式
    @Test
    public void test01() throws ClassNotFoundException {
        //1. Class.forName("全类名")
        Class cls1 = Class.forName("cn.fbd.demo.reflectDemo.domain.Persion");
        System.out.println(cls1);
        //2. 类名.class 属性
        Class cls2 = Persion.class;
        System.out.println(cls2);
        // 3. 对象.getClass() 方法
        Persion p = new Persion();
        Class cls3 = p.getClass();
        System.out.println(cls3);
    }

在这里插入图片描述

  • 结论: 同一个字节码文件(*.class)再一次程序运行过程中,只会被加载一次,无论通过以上哪一种方式获取的Class对象都是同一个

Class对象的常用功能

在这里插入图片描述

package cn.fbd.demo.reflectDemo;


import cn.fbd.demo.reflectDemo.domain.Person;
import org.junit.Test;

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

public class reflectClassTest {

    // 获取Class对象的三种方式
    @Test
    public void test01() throws ClassNotFoundException {
        //1. Class.forName("全类名")
        Class cls1 = Class.forName("cn.fbd.demo.reflectDemo.domain.Person");
        System.out.println(cls1);
        //2. 类名.class 属性
        Class cls2 = Person.class;
        System.out.println(cls2);
        // 3. 对象.getClass() 方法
        Person p = new Person();
        Class cls3 = p.getClass();
        System.out.println(cls3);

        System.out.println(cls1==cls2);
        System.out.println(cls1==cls3);
    }

    /**
     *
     */
    @Test
     public void test02() throws NoSuchFieldException, IllegalAccessException {
         // 获取Persion的Class对象
         Class persionClass = Person.class;
         /**
          * 1. 获取成员变量  public修饰的成员变量
          *     Field[] getFields()    所有的
          *     Field getField(String name) 指定名称的
          *
          *     Declared 暴力获取所有修饰符的成员变量
          *     Field[] getDeclaredFields()
          *     Field[] getDeclareField(String name)
          */
         // 获取所有public修饰的成员变量
         Field[] fields = persionClass.getFields();
         for (Field field: fields
              ) {
             System.out.println(field);
         }
        // 获取指定名称的public修饰的成员变量
         Field a = persionClass.getField("a");
         System.out.println(a);

         // 获取所有修饰符类型的成员变量
        Field[] allFields = persionClass.getDeclaredFields();
        for (Field fields2: allFields
             ) {
            System.out.println(fields2);
        }
        // 获取指定名称修饰符类型的成员变量
        Field a2 = persionClass.getDeclaredField("name");

        System.out.println(a2);
        // 在获取或者设置值之前要设置忽略访问权限修饰符的安全检查
        a2.setAccessible(true);
        //----------
        /**
         * 对成员变量Field的操作
         *  1. 设置值
         *     void set(Object obj,Object value)
         *  2. 获取值
         *     get(Object obj)
         *  3. 忽略访问修饰符的安全检查
         *      setAccessible(true)   暴力反射
         */
        // 获取成员变量的值
        Person p = new Person();
        Object obj = a2.get(p);
        System.out.println(obj);
        // 设置成员变量的值
        a2.set(p,"嘿嘿");
        System.out.println(p);

    }

    /**
     * 获取构造方法
     * @throws Exception
     */
    @Test
    public void test03() throws Exception {
        Class personClass = Person.class;
        // 获取构造方法 有参构造
        Constructor construtor1 = personClass.getConstructor(String.class,Integer.class,String.class);
        System.out.println(construtor1);
        // 创建对象
        Object persion = construtor1.newInstance("老王", 23, "老铁");
        System.out.println(persion);
        System.out.println("=======================");
        // 获取构造方法 无参构造
        Constructor construtor2 = personClass.getConstructor();
        System.out.println(construtor2);
        // 创建对象
        Object persion2 = construtor2.newInstance();
        System.out.println("常规的方式获取空参构造方法: "+persion2);
        // 使用简化的方式获取空参构造方法
        Object o = personClass.newInstance();
        System.out.println("简化的方式获取空参构造方法: "+o);
    }

    /**
     * // 获取成员方法
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    @Test
    public void test04() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        Class person = Person.class;
        Method eat_method = person.getMethod("eat");
        // 执行无参成员方法
        Person p = new Person();
        eat_method.invoke(p);

        // 执行有参数的成员方法
        Method eat_method2 = person.getMethod("eat",String.class);
        eat_method2.invoke(p,"火鸡面!");

        //-------------------
        //获取所有public修饰的方法
        System.out.println("------------------------");
        Method[] methods = person.getMethods();
        for (Method method : methods
             ) {
            System.out.println(method);
            // 获取方法名
            System.out.println(method.getName());
            //method.setAccessible(true);
        }

    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值