反射学习笔记(二) - - 暴力反射 - -

src==> 源文件存放位置
bin==> bean 文件

_____________________________________________________________
=============================================================
++++++++++++++++++++++++  反射  笔记  +++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
_____________________________________________________________
-->
                        面向对象: 万物皆对象
    --> java类 : 类的组成部分
        ( 1 )每个类都有一个package
        ( 2 )每个类有一个类名
        ( 3 )构造方法
        ( 4 )属性
        ( 5 )普通方法
             .......                    静态方法 未包括
=============================================================
       --->     反射的根基 : java 开发者为我们提供了一个类来描述 java  文件 ,这个类为Class
                同时,Class 类型对应的对象可以代表某一个某一个类的字节码文件
                public class  Class  {
                        ......
                     }
                           对象代表字节码文件
                           字节码文件类型  ===>    . class
                          ==================================
    ---> 如何获取某一类的字节码文件?   ====>     获取一个类的对象
    --------------------------------------------------------
    [ 注: 反射不能 new 出来  , 没有 new ]
    三种方式获取:
        --> 通过类名.class
        --> 类名.forName("某个类的全路径")
        --> 对象名 .getClass( )                                    [ - 点不能丢 - ]
    ---------------------------------------------------------
        @Test           //获取User的字节码文件
        public void ReflectionTest1() throws ClassNotFoundException {
            //通过类名获取字节码文件
            Class userClass = User.class;                   <----------   第一种
            //通过.forName获取字节码文件
            Class u = Class.forName("User");                <----------   第二种
            //通过.getClass 获取
            User user = new User();
            Class get =  user.getClass();                   <----------   第三种
            //以上三者获取的是同一个字节码文件 , sout 输出  true
            // 注意       第三种获取的方式需要实例化对象,通过对象的.getClass方法获取
            System.out.println(u==userClass);
            System.out.println(u==get);
        }
     ----------------------------------------------------------
     所有类的底层都是字节码===> 二进制文件
     ----------------------------------------------------------
     * 通过反射创建对象
     * 所谓的反射,将一个类中的  各个成员   映射    成    相对应的   java类型
     *    ==================================================================
     *     各个成员: 包括 { 包 --> package, 构造器 ---> Contructor ,  属性字段 ---> Field ,  普通方法 ----> Method }
     *    ==================================================================
     *
     *  spring 机制 :
     *        <bean id = " xx "  class = " com.xsh.User " ></bean>
     *  ====>  通过   Class.forName( " 类的全路径 ")    获取  字节码文件
     *         以字节码文件为纽带,创建实例.
     *
     ---------------------------------------------------------
                 @Test
                public void ReflectionTest2() throws Exception {
                    // 1/获取字节码文件
                    Class  userClass = Class.forName("User");
                    //2/需要创建一个对象, ===>  创建对象一定需要调用构造方法  调用类中的无参构造方法来创建构造对象
                    Constructor[] constructors = userClass.getConstructors();
                    for (Constructor constructor : constructors ) {             ====>
                        System.out.println(constructor);                        ====> for循环打印所以构造方法
                    }                                                           ====>
                    //通过字节码获取无参构造方法
                    Constructor constructor =userClass.getConstructor();
                    //通过无参构造方法,创建对象
                    User u = (User) constructor.newInstance();
                    System.out.println(u);      ===>   打印出对象: 证明通过映射成功创建对象
                    //通过字节码获取有参构造方法
                    Constructor constructor1 = userClass.getConstructor(String.class,int.class);
                    User uu = (User) constructor1.newInstance("张三",21);        ===> 这里是赋值给通过映射创建的对象
                    System.out.println(uu);     ===>   打印出对象: 证明通过映射成功创建对象
                }
    ------------------------------------------------------------
    反射对象和传统对象效率相比:  反射的效率比传统方式低很多
    ----> 创建一百个对象速度相比,低至 10~ 20 倍   我自己测是这样的 ,  总结就是低很多...量越大,效率越低
    ------------------------------------------------------------
==================================================================================================================
    public class User {
        private String name = "张三李四";           //姓名
        int age = 26;           //年龄
        protected float weight = 60.5F;         //体重
        public float height = 180.5F;       //身高

        构造方法略过....
        }
==================================================================================================================
    1 /  在不给出任何接口的情况下( toString 方法也不给出 )如何获取到User类中私有属性的值  ?   ====>  反射
                -------------------------------------------------------------------------
                     * ==================================================================
                     * 通过反射获取某一个实体对象的属性字段及其值
                     *          1/通过反射获取public.protect,默认修饰符修饰的属性字段和值
                     *          2/通过暴力反射获取 私有属性字段及其值   private 修饰的
                     * ==================================================================
                     *  反射里将属性封装成了field类型 :
                     *          修饰符         数据类型      属性名
                     *      getFields() ===>  只能获取public修饰的属性
                     *      getDeclaredFields  ====>   获取除了私有的之外的三种修饰符修饰的字段   jdk 8   获取全部
                       =================================================================
                    @Test
                    public void test() throws Exception {
                        //创建一个对象
                        Class c = User.class;
                        User user = (User) c.getConstructor().newInstance();
                        //获取user这个对象的属性字段
                        Field[] fields = c.getDeclaredFields();
                        for (Field s : fields ) {                           [ 这里仅仅是部分方法 仅供参考 ]
                            System.out.println(s);
                        }
                        //获取指定字段的属性             [ 默认=> 0  public=>1 protected =>4  private =>2 ]
                        Field field = c.getDeclaredField("weight");
                        System.out.println(field.getType());        //获取字段类型
                        System.out.println(field.getModifiers());   //返回修饰符的值
                        System.out.println(field.getName());    //获取字段名字
                        System.out.println(field.getDeclaringClass().getTypeName());  //获取属性类路径
                    }
                       =================================================================
                           @Test
                           public void test() throws Exception {
                               //创建一个对象
                               Class c = User.class;
                               User user = (User) c.getConstructor().newInstance();
                               //获取user这个对象的属性字段
                               Field[] fields = c.getDeclaredFields();
                               for (Field s : fields ) {
                                //   System.out.println(s);
                               }
                               //获取指定字段的属性
                               Field field = c.getDeclaredField("name");
                               System.out.println(field.getType());        //获取字段类型
                               System.out.println(field.getModifiers());   //返回修饰符的值
                               System.out.println(field.getName());    //获取字段名字
                               System.out.println(field.getDeclaringClass().getTypeName());  //获取属性类路径
                               //暴力反射  ==>  获取所有属性的值   如果某个属性被私有化,想要获取就需要通过暴力反射
                               field.setAccessible(true);
                               Object o = field.get(user);
                               System.out.println(o);
                               //修改某字段值
                               field.set(user,"牛二刘三");
                               System.out.println(user);           //修改成功
                           }
                       =================================================================
========================================================================================================================
         [ 默认=> 0  public=>1 protected =>4  private =>2 ]   为什么没有3?
            1Byte  =    8  bit
            字节          位               计算机底层 二进制    一个字节 ==>  8 位
                                            计算机传输的时候每次最少是一个八位的字节
    1==> 高电压
    0==> 低电压          00000000      0
                         00000010      1*2^0 = 1
                         00000100      1*2^1 = 2
                         00001000      1*2^2 = 4
          这样的传输效率最高 ===   >   所以没有 3  !
========================================================================================================================
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值