單例模式
????????編程中出現(xiàn)了一個問題?
????????如果讓一個類在java內(nèi)存中只創(chuàng)建一個對象 ?
懶漢式/飽漢式
餓漢式
餓漢式進階版
實現(xiàn)步驟
????????????私有化構(gòu)造方法
????????????自己創(chuàng)建對象并記錄住
????????????保證這個變量的安全
總結(jié)
????????????優(yōu)點 :? 節(jié)省靜態(tài)方法區(qū)的內(nèi)存, 使用時效率高
????????????缺點 :? 相對于靜態(tài)來說, 效率還是要低一些
一. 枚舉
? ??定義
????????????????枚舉是一個概念,列舉的意思,將所有的情況都列舉出來那么取值的時候只能是這幾種情況的一種震鹉,不能是別的
???????????????在Java中枚舉可以理解為有限制的多例,在當前類中定義多個實例供別人使用
? ??應用場景
????????????????一個星期只有七天, 我們就可以把這些字符串裝在一個數(shù)組或者集合中供我們使用(這也是枚舉), 但是, 擴展性非常差, 比如, 我們想顯示英文的就必須重寫一次, 使用枚舉類來實現(xiàn), 就是將變量放到一個類中,然后有限制的定義幾個對象使用
注意事項
????????枚舉多用于將一組信息裝載到一個對象中
二. enum關鍵字的枚舉(jdk1.5)
? ??定義
???????????????jdk1.5推出了enum關鍵字來幫助我們簡化格式
????????????????省略了static final 關鍵字和創(chuàng)建對象
????????????????enum關鍵字還能對格式進行檢查
? ??注意事項
????????????????定義枚舉類要用關鍵字enum
????????????????所有枚舉類都是Enum的子類
????????????????枚舉類的第一行上必須是枚舉項阐滩,最后一個枚舉項后的分號是可以省略的交掏,但是如果枚舉類有其他的東西,這個分號就不能省略。建議不要省略
????????????????枚舉類可以有構(gòu)造器,但必須是private的舵揭,它默認的也是private的。
????????????????枚舉類也可以有抽象方法躁锡,但是枚舉項必須重寫該方法
????????????????swicth語句可以使用枚舉
常用方法
????????int ordinal() 獲取枚舉項的序號
????????int compareTo(E o)? 比較兩個枚舉項
????????String name() 獲取枚舉枚舉項的名稱
????????String toString() 獲取枚舉項的字符串表現(xiàn)形式
????????<T> T valueOf(Class<T> type,String name) 使用字節(jié)碼和名稱獲取枚舉項
????????values()
三. 類加載
? ??定義
????????????????當程序要使用某個類時午绳,如果該類還未被加載到內(nèi)存中,則系統(tǒng)會通過加載稚铣,連接箱叁,初始化三步來實現(xiàn)對這個類進行初始化
????加載
????????????????就是指將.class文件讀入內(nèi)存,并為之創(chuàng)建一個Class對象惕医。任何類被使用時系統(tǒng)都會建立一個Class對象。
????連接
????????????????驗證 是否有正確的內(nèi)部結(jié)構(gòu)算色,并和其他類協(xié)調(diào)一致
????????????????準備 負責為類的靜態(tài)成員分配內(nèi)存抬伺,并設置默認初始化值
????????????????解析 將類的二進制數(shù)據(jù)中的符號引用替換為直接引用
? ? ?初始化 就是我們以前講過的初始化步驟
加載的時機(在類真正被使用時)
????????創(chuàng)建類的實例
????????訪問類的靜態(tài)變量,或者為靜態(tài)變量賦值
????????調(diào)用類的靜態(tài)方法
????????使用反射方式來強制創(chuàng)建某個類或接口對應的java.lang.Class對象
????????加載某個類的子類
????????直接使用java.exe命令來運行某個主類
四. 類加載器的概述和分類
? ??????定義
????????????????負責將.class文件加載到內(nèi)存中灾梦,并為之生成對應的Class對象峡钓。雖然我們不需要關心類加載機制,但是了解這個機制我們就能更好的理解程序的運行
? ??????類加載器的分類
????????????????????Bootstrap ClassLoader 根類加載器
????????????????????Extension ClassLoader 擴展類加載器
????????????????????Sysetm ClassLoader 系統(tǒng)類加載器
????????????????????AppClassLoader 應用類加載器
? ??????類加載器的作用
????????????????????BootstrapClassLoader 根類加載器
????????????????????????????????也被稱為引導類加載器若河,負責Java核心類的加載
????????????????????????????????比如System,String等能岩。在JDK中JRE的lib目錄下rt.jar文件中
????????????????????ExtensionClassLoader 擴展類加載器
????????????????????????????????負責JRE的擴展目錄中jar包的加載。
????????????????????????????????在JDK中JRE的lib目錄下ext目錄
????????????????????SysetmClassLoader 系統(tǒng)類加載器
????????????????????????????????負責在JVM啟動時加載來自java命令的class文件萧福,以及classpath環(huán)境變量所指定的jar包和類路徑
????????????????????AppClassLoader 加載其他類
????????????????????????????????負載一些非核心類和程序猿自己寫的類
五. 自定義類加載器
? ??雙親委派模型
????????????????當前類加載器從自己已經(jīng)加載的類中查詢是否此類已經(jīng)加載拉鹃,如果已經(jīng)加載則直接返回原來已經(jīng)加載的類。
????????????????如果沒有找到鲫忍,就去委托父類加載器去加載(如代碼c = parent.loadClass(name, false)所示)膏燕。父類加載器也會采用同樣的策略,查看自己已經(jīng)加載過的類中是否包含這個類悟民,有就返回坝辫,沒有就委托父類的父類去加載,一直到根類加載器射亏。因為如果父加載器為空了近忙,就代表使用根類類加載器作為父加載器去加載
????????????????如果根類類加載器加載失斀咭怠(例如在$JAVA_HOME/jre/lib里未查找到該class),會使用拓展類加載器來嘗試加載及舍,繼續(xù)失敗則會使用AppClassLoader來加載永品,繼續(xù)失敗則會拋出一個異常ClassNotFoundException,然后再調(diào)用當前加載器的findClass()方法進行加載
? ??好處
????????????????主要是為了安全性击纬,避免用戶自己編寫的類動態(tài)替換 Java的一些核心類鼎姐,比如 String。
????????????????同時也避免了類的重復加載更振,因為 JVM中區(qū)分不同類炕桨,不僅僅是根據(jù)類名,相同的 class文件被不同的 ClassLoader加載就是不同的兩個類
六. 反射
? ??定義
????????????JAVA反射機制是在運行狀態(tài)中肯腕,對于任意一個類献宫,都能夠知道這個類的所有屬性和方法
????????????對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性
????????????這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機制
????????????要想解剖一個類,必須先要獲取到該類的字節(jié)碼文件對象
????????????而解剖使用的就是Class類中的方法实撒,所以先要獲取到每一個字節(jié)碼文件對應的Class類型的對象
????????????說白了就是獲取一個類的骨架
? ??獲取字節(jié)碼的三種方式
????????????對象.getClass()
????????????類名.class
????????????Class類中靜態(tài)方法forName("類名")
七. 反射獲取構(gòu)造函數(shù)
? ??定義
????????????????Class類的newInstance()方法是使用該類無參的構(gòu)造函數(shù)創(chuàng)建對象
????????????????如果一個類沒有無參的構(gòu)造函數(shù), 就不能這樣創(chuàng)建了,可以調(diào)用Class類的getConstructor(String.class,int.class)方法獲取一個指定的構(gòu)造函數(shù)然后再調(diào)用Constructor類的newInstance("張三",20)方法創(chuàng)建對象
八. 反射獲取成員變量
? ??定義
????????????????Class.getField(String)方法可以獲取類中的指定字段(可見的)
????????????????如果是私有的可以用getDeclaedField("name")方法獲取
????????????????通過get(obj) 和set(obj, "李四")方法可以獲取和設置指定對象上該字段的值, obj指的是這個類的對象
????????????????如果是私有的需要先調(diào)用setAccessible(true)設置訪問權限放開
九. 反射獲取成員方法
? ??定義
????????????????Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以獲取類中的指定方法
????????????????調(diào)用invoke(Object, Object...)可以調(diào)用對象的這個方法
總結(jié)
????單例模式
????????????模式: 針對某種問題的最優(yōu)解
????????????????????懶漢式, 餓漢式 , 餓漢式的變形體
????????????如何寫單例模式
????????????????????私有化構(gòu)造方法
????????????????????提供自己創(chuàng)建的對象給使用者
???????????優(yōu)點 :
????????????????????節(jié)省內(nèi)存空間,? 提升訪問的速度
????????????缺點 :
????????????????????相對于靜態(tài)來說, 效率還是要低一些
枚舉
????????????枚舉就是多例的簡寫形式
????????????枚舉項的權限, 修飾符, 類型, new 省略
????????????枚舉的注意事項
類加載
????????????就是將.class文件從硬盤上讀取到內(nèi)存中,變成一個java可以使用的類
類加載器
????????????四個類加載器和他們的應用范圍
????????????根類加載器不是java代碼寫的
雙親委派模型
????????????加載一個類的時候,從最底層的類加載器開始逐層上傳, 一直到頂層, 整個過程要檢測這個類有沒有被加載過
????????????作用 : 保持類的唯一性
反射
????????????????反射其實就是java提供的另外一種編程模式
????????????????提高了代碼的兼容性, 擴展性
????????????????反射操作構(gòu)造方法, 操作成員變量, 操作成員方法