反射

B站(UP主:黎曼的猜想 题目:Java基础+进阶)反射观看顺序:5、10、11、6、7、8、9

参考:https://blog.csdn.net/weixin_43691058/article/details/98783120

Java代码在计算机中经历的三个阶段:


    1.源代码阶段(.java、.class文件在硬盘)
    2.Class类对象阶段
        通过类加载器将字节码文件加载到内存,一个类文件对应的是一个类对象
        public class Class{ 
            Field[] fields;//将成员变量封装成对象
            Constructor[] constructors;//将构造函数封装成对象
            Method[] methods;将成员方法封装成对象
            Annotation[] annotations;将注解封装成对象
            //获取成员变量
            Field[] getFields()
            Field getFields(String name)
            Field[] getDeclaredFields()
            Field getDeclaredFields(String name)
            //获取构造方法
            Constructor<?>[] getConstructors()
            Constructor<T> getConstructor(类<?>……parameterTypes)//可变参数
            Constructor<T> getDeclaredConstructor(类<?>……parameterTypes)
            Constructor<?>[] getDeclaredConstructors()
            //获取成员方法
            Method[] getMethods()
            Method getMethods(String name,类<?>……parameterTypes)
            Method[] getDeclaredMethods()
            Method getDeclaredMethods(String name,类<?>……parameterTypes)
            //获取类名
            String getName()
        }
       eg: String这个类的字节文件通过类加载器编程Class对象,把String这个类的成员变量、成员函数等封装成对象。
    3.运行阶段(new 对象)String str = "123";

 

反射:将类的各个部分组成部分封为其他对象

要是想操作这些“其他对象”,重点是找到Class类对象。


    获取Class类对象的方法:


        1:当字节码文件还没有进内存:Class.forName("全类名");//将字节码文件加载到内存,返回Class对象
        2:字节码文件已经在内存,但是没有new 对象();//类名.class:通过类名获取
            Class.forName():使用这个时,会将字节文件加载到内存。所以可使用类名.class;
        3:已经new 对象();//对象.getClass();,getClass这个方法在Object这个类中定义的。


    注意:

           同一个字节码文件(*.class)在一次程序运行过程中,只会加载一次,不论通过哪一种方式获取Class对象都是同一个。

 

找到Class类对象,可以使用它的方法,主要是是获取功能(获取“其他对象”)


        //获取成员变量


            Field[] getFields()//获取public成员变量
            Field getFields(String name)//获取public指定成员变量
            //拿到成员变量Field field = getFields("");可以对成员变量进行设置和获取值
            Object value = field.get(对象);//获取对象的叫name的成员变量的value值。
            field.set(对象,"value值");//对对象叫name的成员变量进行赋值。
        
            Field[] getDeclaredFields()//获取所有的成员变量,不考虑修饰符
            Field getDeclaredFields(String name)
            //拿到成员变量Field field = getDeclaredFields("");可以对成员变量进行设置和获取值(对private也可以赋值,反射面前没有私有还是公有)
            field.setAccessible(true);//忽略访问权限修饰符的安全检查(暴力反射)
            Object value = field.get(对象);//获取对象的叫name的成员变量的value值。
            field.set(对象,"value值");//对对象叫name的成员变量进行赋值。
            

       //获取构造方法


            Constructor<T> getConstructor(类<?>……parameterTypes)//构造函数主要是关注参数列表
            eg:
                Class personClass = Person.class;
                Constructor constructor = personClass.getConstructor(String.class,int.class);
                System.out.println(constructor);
            问题:我们获得constructor这个对象能干什么?换言之,我们得到一个类的构造函数要干什么?
            回答:
                //创建对象
                Object person = constructor.newInstance("张三",23);
                System.out.println(person);
                //创建对象
                Class personClass = Person.class;
                Constructor constructor = personClass.getConstructor();//空参数
                Object person1 = constructor.newInstance();
                System.out.println(person1);
            如果使用空参数进行创建对象时,操作是可以进行简化的
                Class personClass = Person.class;
                Object person2 = personClass.newInstance();
                System.out.println(person2);
    

        //获取成员方法


            //成员函数关注方法名,参数列表,返回值
            Method getMethods(String name,类<?>……parameterTypes)
            //获取指定名称的方法名        
                Class personClass = Person.class;
                Method method = personClass.getMethods("方法名称","参数列表");//空参数
            //得到method对象一般是想执行这个方法
                Object invoke(Object object,Object……args);
            //获取方法名称
                String name = method.getName();
            eg:
                Person person  = new Person();
                method.invoke(person);//method没有参数,就不用传了。
            //有参数
                Class personClass = Person.class;
                Method method1 = personClass.getMethods("eat",String.class);
                method.invoke(person,method1);//method没有参数,就不用传了
                //method方法就可以执行了
            //获取所有的public方法
                Method[] methods = personClass.getMethods();
                for(Method method:methods){
                    System.out.println(method);
                    System.out.println(method.getName());//获取方法名称
                }
                当打印类对象的方法成员Field中包含自己的方法还有Object的方法。


            //获取类名


            Class personClass = Person.class;
            String name = personClass.getName();
            System.out.println(name);//输出的是全类名    


反射的好处


    1:可以在程序运行过程中,操作着希望
    2:可以解耦,可以调高程序的可扩展性。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值