反射

day27授課目錄:

27.01_反射(類的加載概述和加載時(shí)機(jī))

  • A:類的加載概述
    • 當(dāng)程序要使用某個(gè)類時(shí)梅忌,如果該類還未被加載到內(nèi)存中圃酵,則系統(tǒng)會(huì)通過加載击纬,連接泞莉,初始化三步來實(shí)現(xiàn)對這個(gè)類進(jìn)行初始化哪雕。

    • 加載

      • 就是指將class文件讀入內(nèi)存,并為之創(chuàng)建一個(gè)Class對象鲫趁。任何類被使用時(shí)系統(tǒng)都會(huì)建立一個(gè)Class對象斯嚎。
    • 連接

      • 驗(yàn)證 是否有正確的內(nèi)部結(jié)構(gòu),并和其他類協(xié)調(diào)一致
      • 準(zhǔn)備 負(fù)責(zé)為類的靜態(tài)成員分配內(nèi)存挨厚,并設(shè)置默認(rèn)初始化值
      • 解析 將類的二進(jìn)制數(shù)據(jù)中的符號(hào)引用替換為直接引用
    • 初始化 就是我們以前講過的初始化步驟

  • B:加載時(shí)機(jī)
    • 創(chuàng)建類的實(shí)例
    • 訪問類的靜態(tài)變量堡僻,或者為靜態(tài)變量賦值
    • 調(diào)用類的靜態(tài)方法
    • 使用反射方式來強(qiáng)制創(chuàng)建某個(gè)類或接口對應(yīng)的java.lang.Class對象
    • 初始化某個(gè)類的子類
    • 直接使用java.exe命令來運(yùn)行某個(gè)主類

27.02_反射(類加載器的概述和分類)

  • A:類加載器的概述
    • 負(fù)責(zé)將.class文件加載到內(nèi)存中,并為之生成對應(yīng)的Class對象疫剃。雖然我們不需要關(guān)心類加載機(jī)制钉疫,但是了解這個(gè)機(jī)制我們就能更好的理解程序的運(yùn)行。
  • B:類加載器的分類
    • Bootstrap ClassLoader 根類加載器
    • Extension ClassLoader 擴(kuò)展類加載器
    • Sysetm ClassLoader 系統(tǒng)類加載器
  • C:類加載器的作用
    • Bootstrap ClassLoader 根類加載器
      • 也被稱為引導(dǎo)類加載器巢价,負(fù)責(zé)Java核心類的加載
      • 比如System,String等牲阁。在JDK中JRE的lib目錄下rt.jar文件中
    • Extension ClassLoader 擴(kuò)展類加載器
      • 負(fù)責(zé)JRE的擴(kuò)展目錄中jar包的加載固阁。
      • 在JDK中JRE的lib目錄下ext目錄
    • Sysetm ClassLoader 系統(tǒng)類加載器
      • 負(fù)責(zé)在JVM啟動(dòng)時(shí)加載來自java命令的class文件,以及classpath環(huán)境變量所指定的jar包和類路徑

27.03_反射(反射概述)

  • A:反射概述

    • JAVA反射機(jī)制是在運(yùn)行狀態(tài)中咨油,對于任意一個(gè)類您炉,都能夠知道這個(gè)類的所有屬性和方法;
    • 對于任意一個(gè)對象役电,都能夠調(diào)用它的任意一個(gè)方法和屬性赚爵;
    • 這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對象的方法的功能稱為java語言的反射機(jī)制。
    • 要想解剖一個(gè)類,必須先要獲取到該類的字節(jié)碼文件對象法瑟。
    • 而解剖使用的就是Class類中的方法冀膝,所以先要獲取到每一個(gè)字節(jié)碼文件對應(yīng)的Class類型的對象。
  • B:三種方式

    • a:Object類的getClass()方法,判斷兩個(gè)對象是否是同一個(gè)字節(jié)碼文件
    • b:靜態(tài)屬性class,鎖對象
    • c:Class類中靜態(tài)方法forName(),讀取配置文件
  • C:案例演示

    • 獲取class文件對象的三種方式

27.04_反射(Class.forName()讀取配置文件舉例)

  • 榨汁機(jī)(Juicer)榨汁的案例

  • 分別有水果(Fruit)蘋果(Apple)香蕉(Banana)桔子(Orange)榨汁(squeeze)

      public class Demo2_Reflect {
    
          /**
           * 榨汁機(jī)(Juicer)榨汁的案例
           * 分別有水果(Fruit)蘋果(Apple)香蕉(Banana)桔子(Orange)榨汁(squeeze)
           * @throws Exception 
           */
          public static void main(String[] args) throws Exception {
              /*Juicer j = new Juicer();
              //j.run(new Apple());
              j.run(new Orange());*/
              BufferedReader br = new BufferedReader(new FileReader("config.properties"));    //創(chuàng)建輸入流對象,關(guān)聯(lián)配置文件
              Class<?> clazz = Class.forName(br.readLine());                                  //讀取配置文件一行內(nèi)容,獲取該類的字節(jié)碼對象
              Fruit f = (Fruit) clazz.newInstance();                                          //通過字節(jié)碼對象創(chuàng)建實(shí)例對象
              Juicer j = new Juicer();
              j.run(f);
          }
      
      }
      interface Fruit {
          public void squeeze();
      }
      
      class Apple implements Fruit {
          public void squeeze() {
              System.out.println("榨出一杯蘋果汁兒");
          }
      }
      
      class Orange implements Fruit {
          public void squeeze() {
              System.out.println("榨出一杯桔子汁兒");
          }
      }
      
      class Juicer {
          public void run(Fruit f) {
              f.squeeze();
          }
      
      }
    

27.05_反射(通過反射獲取帶參構(gòu)造方法并使用)

  • Constructor
    • Class類的newInstance()方法是使用該類無參的構(gòu)造函數(shù)創(chuàng)建對象, 如果一個(gè)類沒有無參的構(gòu)造函數(shù), 就不能這樣創(chuàng)建了,可以調(diào)用Class類的getConstructor(String.class,int.class)方法獲取一個(gè)指定的構(gòu)造函數(shù)然后再調(diào)用Constructor類的newInstance("張三",20)方法創(chuàng)建對象

27.06_反射(通過反射獲取成員變量并使用)

  • Field
    • Class.getField(String)方法可以獲取類中的指定字段(可見的), 如果是私有的可以用getDeclaedField("name")方法獲取,通過set(obj, "李四")方法可以設(shè)置指定對象上該字段的值, 如果是私有的需要先調(diào)用setAccessible(true)設(shè)置訪問權(quán)限,用獲取的指定的字段調(diào)用get(obj)可以獲取指定對象中該字段的值

27.07_反射(通過反射獲取方法并使用)

  • Method
    • Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以獲取類中的指定方法,調(diào)用invoke(Object, Object...)可以調(diào)用該方法,Class.getMethod("eat") invoke(obj) Class.getMethod("eat",int.class) invoke(obj,10)

27.08_反射(通過反射越過泛型檢查)

  • A:案例演示
    • ArrayList<Integer>的一個(gè)對象霎挟,在這個(gè)集合中添加一個(gè)字符串?dāng)?shù)據(jù)窝剖,如何實(shí)現(xiàn)呢?

27.09_反射(通過反射寫一個(gè)通用的設(shè)置某個(gè)對象的某個(gè)屬性為指定的值)

  • A:案例演示
    • public void setProperty(Object obj, String propertyName, Object value){}酥夭,此方法可將obj對象中名為propertyName的屬性的值設(shè)置為value赐纱。

27.10_反射(練習(xí))

  • 已知一個(gè)類,定義如下:
    • package cn.itcast.heima;
    •  public class DemoClass {
           public void run() {
               System.out.println("welcome to heima!");
           }
       }
      
    • (1) 寫一個(gè)Properties格式的配置文件熬北,配置類的完整名稱疙描。
    • (2) 寫一個(gè)程序,讀取這個(gè)Properties配置文件讶隐,獲得類的完整名稱并加載這個(gè)類起胰,用反射的方式運(yùn)行run方法。

27.11_反射(動(dòng)態(tài)代理的概述和實(shí)現(xiàn))

  • A:動(dòng)態(tài)代理概述
    • 代理:本來應(yīng)該自己做的事情巫延,請了別人來做效五,被請的人就是代理對象。

    • 舉例:春季回家買票讓人代買

    • 動(dòng)態(tài)代理:在程序運(yùn)行過程中產(chǎn)生的這個(gè)對象,而程序運(yùn)行過程中產(chǎn)生對象其實(shí)就是我們剛才反射講解的內(nèi)容炉峰,所以畏妖,動(dòng)態(tài)代理其實(shí)就是通過反射來生成一個(gè)代理

    • 在Java中java.lang.reflect包下提供了一個(gè)Proxy類和一個(gè)InvocationHandler接口,通過使用這個(gè)類和接口就可以生成動(dòng)態(tài)代理對象疼阔。JDK提供的代理只能針對接口做代理瓜客。我們有更強(qiáng)大的代理cglib,Proxy類中的方法創(chuàng)建動(dòng)態(tài)代理類對象

    • public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

    • 最終會(huì)調(diào)用InvocationHandler的方法

    • InvocationHandler Object invoke(Object proxy,Method method,Object[] args)

27.12_設(shè)計(jì)模式(模版設(shè)計(jì)模式概述和使用)

  • A:模版設(shè)計(jì)模式概述
    • 模版方法模式就是定義一個(gè)算法的骨架竿开,而將具體的算法延遲到子類中來實(shí)現(xiàn)
  • B:優(yōu)點(diǎn)和缺點(diǎn)
    • a:優(yōu)點(diǎn)
      • 使用模版方法模式,在定義算法骨架的同時(shí)玻熙,可以很靈活的實(shí)現(xiàn)具體的算法否彩,滿足用戶靈活多變的需求
    • b:缺點(diǎn)
      • 如果算法骨架有修改的話,則需要修改抽象類
        1,裝飾
        2,單例
        3,簡單工廠
        4,工廠方法
        5,適配器
        6,模版

27.13_JDK5新特性(自己實(shí)現(xiàn)枚舉類)

  • A:枚舉概述
    • 是指將變量的值一一列出來,變量的值只限于列舉出來的值的范圍內(nèi)嗦随。舉例:一周只有7天列荔,一年只有12個(gè)月等敬尺。
  • B:回想單例設(shè)計(jì)模式:單例類是一個(gè)類只有一個(gè)實(shí)例
    • 那么多例類就是一個(gè)類有多個(gè)實(shí)例,但不是無限個(gè)數(shù)的實(shí)例贴浙,而是有限個(gè)數(shù)的實(shí)例砂吞。這才能是枚舉類。
  • C:案例演示
    • 自己實(shí)現(xiàn)枚舉類
      1,自動(dòng)拆裝箱
      2,泛型
      3,可變參數(shù)
      4,靜態(tài)導(dǎo)入
      5,增強(qiáng)for循環(huán)
      6,互斥鎖
      7,枚舉

27.14_JDK5新特性(通過enum實(shí)現(xiàn)枚舉類)

  • A:案例演示
    • 通過enum實(shí)現(xiàn)枚舉類

27.15_JDK5新特性(枚舉的注意事項(xiàng))

  • A:案例演示
    • 定義枚舉類要用關(guān)鍵字enum
    • 所有枚舉類都是Enum的子類
    • 枚舉類的第一行上必須是枚舉項(xiàng)崎溃,最后一個(gè)枚舉項(xiàng)后的分號(hào)是可以省略的蜻直,但是如果枚舉類有其他的東西,這個(gè)分號(hào)就不能省略袁串。建議不要省略
    • 枚舉類可以有構(gòu)造器概而,但必須是private的,它默認(rèn)的也是private的囱修。枚舉項(xiàng)的用法比較特殊:枚舉(“”);
    • 枚舉類也可以有抽象方法赎瑰,但是枚舉項(xiàng)必須重寫該方法
    • 枚舉在switch語句中的使用

27.16_JDK5新特性(枚舉類的常見方法)

  • A:枚舉類的常見方法
    • int ordinal()
    • int compareTo(E o)
    • String name()
    • String toString()
    • <T> T valueOf(Class<T> type,String name)
    • values()
    • 此方法雖然在JDK文檔中查找不到,但每個(gè)枚舉類都具有該方法破镰,它遍歷枚舉類的所有枚舉值非常方便
  • B:案例演示
    • 枚舉類的常見方法

27.17_JDK7新特性(JDK7的六個(gè)新特性回顧和講解)

  • A:二進(jìn)制字面量
  • B:數(shù)字字面量可以出現(xiàn)下劃線
  • C:switch 語句可以用字符串
  • D:泛型簡化,菱形泛型
  • E:異常的多個(gè)catch合并,每個(gè)異常用或|
  • F:try-with-resources 語句

27.18_JDK8新特性(JDK8的新特性)

  • 接口中可以定義有方法體的方法,如果是非靜態(tài),必須用default修飾
  • 如果是靜態(tài)的就不用了

27.19_day27總結(jié)

  • 把今天的知識(shí)點(diǎn)總結(jié)一遍餐曼。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鲜漩,隨后出現(xiàn)的幾起案子源譬,更是在濱河造成了極大的恐慌,老刑警劉巖宇整,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓶佳,死亡現(xiàn)場離奇詭異,居然都是意外死亡鳞青,警方通過查閱死者的電腦和手機(jī)霸饲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來臂拓,“玉大人厚脉,你說我怎么就攤上這事〗憾瑁” “怎么了傻工?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵山析,是天一觀的道長令花。 經(jīng)常有香客問我,道長雾消,這世上最難降的妖魔是什么坊饶? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任泄伪,我火速辦了婚禮,結(jié)果婚禮上匿级,老公的妹妹穿的比我還像新娘蟋滴。我一直安慰自己染厅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布津函。 她就那樣靜靜地躺著,像睡著了一般尔苦。 火紅的嫁衣襯著肌膚如雪涩馆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天蕉堰,我揣著相機(jī)與錄音凌净,去河邊找鬼。 笑死屋讶,一個(gè)胖子當(dāng)著我的面吹牛冰寻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播皿渗,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼斩芭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乐疆?” 一聲冷哼從身側(cè)響起划乖,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挤土,沒想到半個(gè)月后琴庵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仰美,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年迷殿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咖杂。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡庆寺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诉字,到底是詐尸還是另有隱情懦尝,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布壤圃,位于F島的核電站陵霉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏伍绳。R本人自食惡果不足惜撩匕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望墨叛。 院中可真熱鬧止毕,春花似錦、人聲如沸漠趁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闯传。三九已至谨朝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間甥绿,已是汗流浹背字币。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留共缕,地道東北人洗出。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像图谷,于是被迫代替她去往敵國和親翩活。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容