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的流量,應該夠了

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