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包和類路徑
- Bootstrap ClassLoader 根類加載器
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,模版
- 如果算法骨架有修改的話,則需要修改抽象類
- a:優(yōu)點(diǎn)
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,枚舉
- 自己實(shí)現(xiàn)枚舉類
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é)一遍餐曼。