了解java反射(reflect)

定义

  • 将类的各个组成部分封装为其他对象,这就是反射机制.反射是开发框架的灵魂.

获取Class字节码中类的三种方法

  1. Class.forName("全类名"),将字节码加载进内存,返回class对象---多用于配置文件
  2. 类名.class:通过类名的属性class获取---多用于传参
  3. 对象.getclass():getclass在Object对象中定义---多用于对象的字节码获取

同一个字节码(*.class)在程序运行中只会被加载一次,所以无论用什么方法获取都是同一个字节码

代码:获取成员变量,方法,构造器,类名的方法

public class Reflect
{
    public static void main(String[] args) throws Exception
    {
        //方法1
        Class cls1 = Class.forName("java_study.Book");
        System.out.println(cls1);

        //方法2
        Class cls2 = Book.class;
        System.out.println(cls2);

        //方法3
        Book b = new Book(50);
        Class cls3 = b.getClass();
        System.out.println(cls3);

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

        //获取public成员变量
        Field[] fs = cls1.getFields();
        for(Field f:fs)
        {
            System.out.println(f);
        }

        //获取成员变量后进行操作:get和set
        Field date = cls1.getField("date");
        Book b2 = new Book(56);
        Object value = date.get(b2);//参数是传入一个该类的对象
        System.out.println(value);
        date.set(b2,"2020-40-20");
        System.out.println(b2);

        //不考虑修饰符,获取所有成员变量
        Field[] fields2 = cls2.getDeclaredFields();
        for(Field f:fields2)
        {
            System.out.println(f);
        }

        //修改私有成员变量时会报错,需要忽略安全检查,暴力反射
        Field name = cls2.getDeclaredField("name");
        name.setAccessible(true);//忽略安全检查
        Book b3 = new Book(100);
        Object v2 = name.get(b3);
        name.set(b3,"格局");
        System.out.println(b3);

        //获取构造方法
        Constructor constructor = cls3.getConstructor(String.class,int.class,int.class);//里面是传入构造参数
        System.out.println(constructor);

        //获取构造器的目的就是用来创建对象
        //创建对象
        Object book4 = constructor.newInstance("一千零一夜",4,52);
        System.out.println(book4);

        //获取成员方法,作用就是执行方法
        Method show = cls1.getMethod("showbook");
        Method setName = cls1.getMethod("setName", String.class);
        setName.invoke(book4,"平凡的世界");
        show.invoke(book4);//用invoke方法执行方法,第二个参数是方法的参数,第一个是对象

        //获取所有Public方法,包括Object的方法
        Method[] ms = cls1.getMethods();

        for(Method m:ms)
        {
            m.setAccessible(true);//暴力映射
            String M_name = m.getName();//获取方法名称
            System.out.println(m);
            System.out.println(M_name);
        }

        //获取类名
        String className = cls1.getName();
        System.out.println(className);
    }
}

反射框架一般步骤

  1. 将需要创建对象的全类名和方法定义在配置文件中
  2. 在程序中读取配置文件
  3. 使用反射技术加载类文件进入内存
  4. 创建对象,执行方法
    * 需求:写一个“框架”,可以传入任意类,并且用该类创建对象,然后执行其中任意方法
     *框架类的前提就是:不能改变该框架类的任何代码,并且能创建任意类的对象,执行任意方法
     *实现:配置文件,反射
     *步骤:1.将需要创建对象的全类名和方法定义在配置文件中
     * 2.在程序中读取配置文件
     * 3.使用反射技术加载类文件进入内存
     * 4.创建对象
     * 5.执行方法
     */
    public class ReflectExample
    {
        public static void main(String[] args) throws Exception
        {
            //1.加载配置文件:创建properties对象,它是一个集合map
            Properties properties = new Properties();
            ClassLoader classLoader = ReflectExample.class.getClassLoader();//字节码加载器
            InputStream is = classLoader.getResourceAsStream("config.properties");//获取配置文件中的字节流
            properties.load(is);
    
            //2.获取配置文件中定义的数据
            String className = properties.getProperty("className");//获取内容
            String methodName = properties.getProperty("methodName");
    
            //3.加载该类进内存
            Class cls = Class.forName(className);//就是转换为.class字节码
    
            //4.创建对象
            Object obj = cls.newInstance();
    
            //5.获取方法
            Method method = cls.getMethod(methodName);
    
            //6.执行方法
            method.invoke(obj);
        }
    }

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值