12345反射

#day15-反射
***
##0. 反射引入
    1. 软件框架:为了实现某一些功能专门封装的具有高通用性的代码
    2. 反射:可以提高代码的通用性
    3. 反射一般在框架中比较常见,我们称反射为框架技术。
    
##1. JUnit单元测试
    1. 框架,eclipse自动集成
    
    2. 注意点
        1. 一定要有注解@Test :初始化错误
        2. 权限必须public
        3. 返回值必须void
        4. 测试方法不能有参数
    3. 三个测试
        1. @Before(test之前 ):  用于初始化
        2. @Test(测试方法)
        3. @After(之后):一般用于释放资源
##2. 类加载(了解)
1. 类加载的过程
    1. 类加载器将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内
    2. 然后在堆区创建一个 java.lang.Class对象,用来封装类在方法区内的数据结构.
        1. 只有Java虚拟机才能创建Class类的对象.
        2. 作用
            1. Class对象封装了类在方法区内的数据结构 ,并且向Java程序员提供了访问方法区内的数据结构的接口,这些接口都定义在了 `反射` 包中.
            2. 可以间接创建对象,调用方法和属性赋值
    3. Class对象和普通对象的区别
        1. Class对象:表示正在运行的 Java 程序中的类和接口(该类的结构信息)
        2. 普通对象:该类的实例(该类的具体化)
        
2. 类加载器
    1. 概述
        1. JDK 提供的代码.
            1. 运行时代码.                    `引导类加载器`
            2. 扩展代码.                        `扩展类加载器`
        2. 自己编写的代码.(以及第三方包)        `应用类加载器`
    2. 三种类加载器
        1. 引导类加载器(Bootstrap ClassLoader)
            1. 负责加载$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++实现,不是ClassLoader子类

            2. 扩展类加载器(Extension ClassLoader)
                1. 负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中jre/lib/*.jar(jre/lib/ext)
                2. Properties -> BuildPath -> Library  -> JRE System -> Access rules -> Edit -> add -> sun/** 

            3. 应用类加载器:(Application ClassLoader)
                1. 加载编写的代码
                
        2. 继承关系
            1. 引导类加载器由C++实现,不是ClassLoader子类(属于JVM的一部分)
            2. 扩展类加载器是引导类加载器子类
            3. 应用类加载器是扩展类加载器子类

    3. 一个class文件只会加载一次,在内存有且只有一个Class对象
    
        1. 如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的加载器都是如此,因此所有的类加载请求都会传给顶层的启动类加载器
        2. 只有当父加载器反馈自己无法完成该加载请求(该加载器的搜索范围中没有找到对应的类)时,子加载器才会尝试自己去加载。
    
##3. 反射
1. Class对象
    1. 反射:在运行时通过代码操作类。(无需知道具体的类,由调用者告知)
        1. 要想操作类必就必须先获得该类的字节码对象Class 对象
        2. 创建实例的两种方式:
            1. new 类名:通过方法区的类结构创建
            2. 反射:通过堆区的Class对象间接创建
    2. 获取Class对象的三种方式
        1. Class.forName(全限定名);            `包名 + 类名`
             1. 使用场景 : 加载外部的配置文件.
         2. 类名.class;
            1. 使用场景: 确定方法形参类型.
            2. 确定方法的两个条件(重载): 1. 方法名.    2. 参数列表
        3. 对象名.getClass();
             1. 使用场景 : 方法内部确定形参的真实类型.
             
2. 使用反射调用构造方法创建对象
    0. Student类用于测试
        1. 两个private属性,一个public属性
        2. 两个public构造(有参、无参),一个private有参构造
        3. 方法:普通方法(公开、私有) 静态方法(main函数)
        4. 设置 get set tostring 方法
    1. 需求:创建一个Student类对象
        1. 使用反射调用公开的无参构造方法创建对象.
            1. 获取堆区中的Class对象
            2. 使用 cls 对象调用 newInstance() 方法创建一个 `方法区` 中该类的对象.
        2. 使用反射调用公开的有参构造方法创建对象.
            1. 获取堆区中的Class对象
            2. 使用 cls 对象调用 getConstructor(...) 方法获取方法区中该类表示的 `构造方法` 对象
            3. 使用 constructor 对象调用 newInstance(...) 方法创建该类的实例对象, 并传递实际参数列表
        3. 使用反射调用私有构造方法创建对象.
            1. 获取堆区中的Class对象
            2. 使用 cls 对象调用 getDeclaredConstructor(...) 方法获取方法区中该类表示的 `构造方法` 对象(包括私有方法)
            3. 使用 constructor 对象调用 setAccessible(true) 设置该私有构造方法的 `暴力访问`.(设置权限)
            4. 使用 constructor 对象调用 newInstance(...) 方法创建该类的实例对象, 并传递实际参数列表
            
3. 使用反射执行方法
    1. 使用反射执行公开的对象方法.
        1. 获取堆区中的 Class 对象, 并直接使用 cls 对象调用 newInstance() 方法创建该类的实例对象
        2. 使用 cls 对象调用 getMethod(...) 方法, 获取该类对象调用的 `方法对象`
        3. 使用方法对象调用 invoke, 执行该方法

    2. 使用反射执行私有的对象方法.
        1. 获取堆区中的 Class 对象, 并直接使用 cls 对象调用 newInstance() 方法创建该类的实例对象
        2. 使用 cls 对象调用 getDeclaredMethod(...) 方法获取私有的 `方法对象`.
        3. 由于 `方法对象` 是一个私有的方法, 需要设置该方法的暴力访问
        4. 使用  `方法对象` 调用 invoke 方法, 执行该方法

    3. 使用反射执行静态方法. 特点: 参数列表为 `数组类型`
        1. 获取堆区中的 Class 对象
        2. 使用 cls对象调用 getMethod(...) 获取该类的方法对象
        3. 使用方法对象调用 invoke 方法, 执行该方法.

4. 使用反射设置属、获取属性值
    1. 使用反射给公开的属性赋值和取值.
        1. 获取堆区中的 Class 对象, 使用 cls 对象调用 newInstance() 方法创建该类的实例对象
        2. 使用 cls 对象调用 getField(...) 方法, 获取属性对象
        3. 使用属性对象调用 set(...) 方法为指定对象的该属性赋值

    2. 使用反射给私有的属性赋值.
        1. 获取堆区中的 Class 对象, 使用 cls 对象调用 newInstance() 方法创建该类的实例对象
        2. 使用 cls 对象调用 getDeclaredField(...) 方法, 获取属性对象
        3. 使用属性对象调用 setAccessible(true) 设置该私有属性的暴力方法
        4. 使用属性对象调用 set(...) 方法为指定对象的该属性赋值
##4. 综合案例(举办晚会)
1.  工厂设计模式:主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

2. 关于设计模式
    1. 设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。
    2. 目的:设计模式是软件工程的基石脉络,如同大厦的结构一样。为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。
    3. 意义:代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用
    4. 总结:
        1. 设计模式的深入理解和应用需要一定的开发经验和学习能力
        2. 设计模式是代码的编写套路,并不能提高代码执行效率!
        3. 不同的设计模式适用于不同的需求场景,不能生搬硬套
        4. 掌握设计模式是自然而然,水到渠成的过程。不强求,暂时不理解不影响开发

## 关于翻墙
1. google浏览器 + google访问助手(插件)
2. 同学分享:分享给大家一个免费而且非常好用的的翻墙办法,亚马逊有一年免费的AWS服务器,然后在日本服务器,搭建好shadowscock,记住服务器IP和端口名,电脑和手机就可以科学上网了,一个月15个G的流量,应该够了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章