2020-06-02--單例枚舉反射

單例模式

編程中出現(xiàn)了一個(gè)問題?

如果讓一個(gè)類在java內(nèi)存中只創(chuàng)建一個(gè)對(duì)象 ?

懶漢式/飽漢式

//懶漢式 ? 飽漢式

publicclassMyTool{

?

? ? privatestaticMyToolmyTool=null;

? ? //私有話構(gòu)造方法, 讓使用者無法new對(duì)象

? ? //這樣使用者就沒有辦法創(chuàng)建多個(gè)對(duì)象了

? ? privateMyTool(){}

? ? //提供一個(gè)靜態(tài)方法, 使用者調(diào)用這個(gè)方法可以獲取對(duì)象

? ? //這樣,我們就可以控制創(chuàng)建的對(duì)象了

? ? publicstaticMyToolgetInstance(){

? ? ? ? //第一次訪問時(shí),發(fā)現(xiàn)變量中沒有記錄對(duì)象, 就新建對(duì)象

? ? ? ? //如果已經(jīng)創(chuàng)建過對(duì)象,就直接返回

? ? ? ? if(myTool==null){

? ? ? ? ? ? myTool=newMyTool();

? ? ? ? }


? ? ? ? returnmyTool;

? ? }


? ? publicStringencoding(Stringstr){


? ? ? ? return"";

? ? }

}

?

餓漢式

//餓漢式

publicclassMyTool2{

?

? ? privatestaticMyTool2myTool=newMyTool2();

? ? //私有話構(gòu)造方法, 讓使用者無法new對(duì)象

? ? //這樣使用者就沒有辦法創(chuàng)建多個(gè)對(duì)象了

? ? privateMyTool2(){}

? ? //提供一個(gè)靜態(tài)方法, 使用者調(diào)用這個(gè)方法可以獲取對(duì)象

? ? //這樣,我們就可以控制創(chuàng)建的對(duì)象了

? ? publicstaticMyTool2getInstance(){


? ? ? ? returnmyTool;

? ? }


? ? publicStringencoding(Stringstr){


? ? ? ? return"";

? ? }

}

?

//餓漢式

publicclassMyTool3{

?

? ? publicstaticfinalMyTool3MY_TOOL=newMyTool3();

? ? //私有話構(gòu)造方法, 讓使用者無法new對(duì)象

? ? //這樣使用者就沒有辦法創(chuàng)建多個(gè)對(duì)象了

? ? privateMyTool3(){}

?


? ? publicStringencoding(Stringstr){


? ? ? ? return"";

? ? }

}

實(shí)現(xiàn)步驟

私有化構(gòu)造方法

自己創(chuàng)建對(duì)象并記錄住

保證這個(gè)變量的安全

總結(jié)

優(yōu)點(diǎn) :? 節(jié)省靜態(tài)方法區(qū)的內(nèi)存, 使用時(shí)效率高

缺點(diǎn) :? 相對(duì)于靜態(tài)來說, 效率還是要低一些

一. 枚舉

定義

枚舉是一個(gè)概念,列舉的意思,將所有的情況都列舉出來那么取值的時(shí)候只能是這幾種情況的一種,不能是別的

在Java中枚舉可以理解為有限制的多例,在當(dāng)前類中定義多個(gè)實(shí)例供別人使用

應(yīng)用場景

一個(gè)星期只有七天, 我們就可以把這些字符串裝在一個(gè)數(shù)組或者集合中供我們使用(這也是枚舉), 但是, 擴(kuò)展性非常差, 比如, 我們想顯示英文的就必須重寫一次, 使用枚舉類來實(shí)現(xiàn), 就是將變量放到一個(gè)類中,然后有限制的定義幾個(gè)對(duì)象使用

格式

空參構(gòu)造的枚舉類(沒有意義)

publicclassWeek{


? ? publicstaticfinalWeekMON=newWeek();

? ? publicstaticfinalWeekTUE=newWeek();

? ? publicstaticfinalWeekWED=newWeek();

? ? publicstaticfinalWeekTHU=newWeek();

? ? publicstaticfinalWeekFRI=newWeek();

? ? publicstaticfinalWeekSAT=newWeek();

? ? publicstaticfinalWeekSUN=newWeek();

}

有參構(gòu)造的枚舉類

publicclassWeek{


? ? publicstaticfinalWeekMON=newWeek("星期一");

? ? publicstaticfinalWeekTUE=newWeek("星期二");

? ? publicstaticfinalWeekWED=newWeek("星期三");

? ? publicstaticfinalWeekTHU=newWeek("星期四");

? ? publicstaticfinalWeekFRI=newWeek("星期五");

? ? publicstaticfinalWeekSAT=newWeek("星期六");

? ? publicstaticfinalWeekSUN=newWeek("星期日");

? ? privateStringname;

? ? //私有化構(gòu)造

? ? privateWeek(Stringname){

? ? ? ? this.name=name;

? ? }

? ? //提供getter方法,便于別人使用

? ? publicStringgetName() {

? ? ? ? returnname;

? ? }

?

}

有方法的枚舉類

publicclassWeek{


? ? publicstaticfinalWeekMON=newWeek("星期一");

? ? publicstaticfinalWeekTUE=newWeek("星期二");

? ? publicstaticfinalWeekWED=newWeek("星期三");

? ? publicstaticfinalWeekTHU=newWeek("星期四");

? ? publicstaticfinalWeekFRI=newWeek("星期五");

? ? publicstaticfinalWeekSAT=newWeek("星期六");

? ? publicstaticfinalWeekSUN=newWeek("星期日");

? ? publicStringname;

? ? //私有化構(gòu)造

? ? privateWeek(Stringname){

? ? ? ? this.name=name;

? ? }

? ? //提供getter方法,便于別人使用

? ? publicStringgetName() {

? ? ? ? returnname;

? ? }

? ? //提供特殊方法

? ? publicvoidshow(){

? ? ? ? System.out.println("今天是"+name);

? ? }

}

包含抽象方法的枚舉類

publicabstractclassWeek{


? ? privatestaticfinalWeekMON=newWeek("星期一"){

? ? ? ? publicvoidshow(){

? ? ? ? ? ? System.out.println("星期一好難受");

? ? ? ? }


? ? };

? ? privatestaticfinalWeekTUE=newWeek("星期二"){

? ? ? ? publicvoidshow(){

? ? ? ? ? ? System.out.println("星期二暈暈乎乎");

? ? ? ? }


? ? };

? ? privatestaticfinalWeekWED=newWeek("星期三"){

? ? ? ? publicvoidshow(){

? ? ? ? ? ? System.out.println("咦,星期三了...");

? ? ? ? }


? ? };

? ? privatestaticfinalWeekTHU=newWeek("星期四"){

? ? ? ? publicvoidshow(){

? ? ? ? ? ? System.out.println("趕緊,趕緊,今天快點(diǎn)結(jié)束");

? ? ? ? }


? ? };

? ? privatestaticfinalWeekFRI=newWeek("星期五"){

? ? ? ? publicvoidshow(){

? ? ? ? ? ? System.out.println("哇,好棒,星期五了");

? ? ? ? }


? ? };

? ? privatestaticfinalWeekSAT=newWeek("星期六"){

? ? ? ? publicvoidshow(){

? ? ? ? ? ? System.out.println("睡的真舒服");

? ? ? ? }


? ? };

? ? privatestaticfinalWeekSUN=newWeek("星期日"){

? ? ? ? publicvoidshow(){

? ? ? ? ? ? System.out.println("好開心哦, 時(shí)間慢慢走哈");

? ? ? ? }


? ? };

? ? privateStringname;

? ? //私有化構(gòu)造

? ? privateWeek(Stringname){

? ? ? ? this.name=name;

? ? }

? ? //提供getter方法,便于別人使用

? ? publicStringgetName() {

? ? ? ? returnname;

? ? }


? ? publicabstractvoidshow();

}

注意事項(xiàng)

枚舉多用于將一組信息裝載到一個(gè)對(duì)象中

測試題

使用枚舉模擬撲克牌的制作牌的過程

二. enum關(guān)鍵字的枚舉(jdk1.5)

定義

jdk1.5推出了enum關(guān)鍵字來幫助我們簡化格式

省略了static final 關(guān)鍵字和創(chuàng)建對(duì)象

enum關(guān)鍵字還能對(duì)格式進(jìn)行檢查

演示

publicenumWeek2{

? ? //定義變量,指向?qū)ο?/p>

? ? MON("星期一") ,TUE("星期二") ,WED("星期三") ,THU("星期四") ,FRI("星期五") ,SAT("星期六") ,SUN("星期日") ;


? ? Stringname;

? ? //私有化構(gòu)造

? ? privateWeek2(Stringname){

? ? ? ? this.name=name;

? ? }

?

? ? publicStringgetName() {

? ? ? ? returnname;

? ? }

}

注意事項(xiàng)

定義枚舉類要用關(guān)鍵字enum

所有枚舉類都是Enum的子類

枚舉類的第一行上必須是枚舉項(xiàng)逗爹,最后一個(gè)枚舉項(xiàng)后的分號(hào)是可以省略的昔期,但是如果枚舉類有其他的東西怀吻,這個(gè)分號(hào)就不能省略。建議不要省略

枚舉類可以有構(gòu)造器约啊,但必須是private的,它默認(rèn)的也是private的。

枚舉類也可以有抽象方法拙徽,但是枚舉項(xiàng)必須重寫該方法

swicth語句可以使用枚舉

案例

publicstaticvoidmain(String[]args) {

? ? Week2week2=Week2.MON;

? ? switch(week2) {

? ? caseFRI:

? ? ? ? ? ? System.out.println("好高興哦");

? ? ? ? break;

? ? caseMON:

? ? ? ? System.out.println("過了星期三,越過越心寬");

? ? ? ? break;

? ? default:

? ? ? ? System.out.println("沒有了");

? ? ? ? break;

? ? }

}

常用方法

int ordinal() 獲取枚舉項(xiàng)的序號(hào)

int compareTo(E o)? 比較兩個(gè)枚舉項(xiàng)

String name() 獲取枚舉枚舉項(xiàng)的名稱

String toString() 獲取枚舉項(xiàng)的字符串表現(xiàn)形式

<T> T valueOf(Class<T> type,String name) 使用字節(jié)碼和名稱獲取枚舉項(xiàng)

values()

此方法雖然在JDK文檔中查找不到,但每個(gè)枚舉類都具有該方法诗宣,它遍歷枚舉類的所有枚舉值非常方便

三. 類加載

定義

當(dāng)程序要使用某個(gè)類時(shí)膘怕,如果該類還未被加載到內(nèi)存中,則系統(tǒng)會(huì)通過加載梧田,連接淳蔼,初始化三步來實(shí)現(xiàn)對(duì)這個(gè)類進(jìn)行初始化

加載

就是指將.class文件讀入內(nèi)存,并為之創(chuàng)建一個(gè)Class對(duì)象裁眯。任何類被使用時(shí)系統(tǒng)都會(huì)建立一個(gè)Class對(duì)象鹉梨。

連接

驗(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)引用替換為直接引用

初始化 就是我們以前講過的初始化步驟

加載的時(shí)機(jī)(在類真正被使用時(shí))

創(chuàng)建類的實(shí)例

訪問類的靜態(tài)變量存皂,或者為靜態(tài)變量賦值

調(diào)用類的靜態(tài)方法

使用反射方式來強(qiáng)制創(chuàng)建某個(gè)類或接口對(duì)應(yīng)的java.lang.Class對(duì)象

加載某個(gè)類的子類

直接使用java.exe命令來運(yùn)行某個(gè)主類

四. 類加載器的概述和分類

定義

負(fù)責(zé)將.class文件加載到內(nèi)存中,并為之生成對(duì)應(yīng)的Class對(duì)象。雖然我們不需要關(guān)心類加載機(jī)制旦袋,但是了解這個(gè)機(jī)制我們就能更好的理解程序的運(yùn)行

類加載器的分類

Bootstrap ClassLoader 根類加載器

Extension ClassLoader 擴(kuò)展類加載器

Sysetm ClassLoader 系統(tǒng)類加載器

AppClassLoader 應(yīng)用類加載器

類加載器的作用

BootstrapClassLoader 根類加載器

也被稱為引導(dǎo)類加載器骤菠,負(fù)責(zé)Java核心類的加載

比如System,String等。在JDK中JRE的lib目錄下rt.jar文件中

ExtensionClassLoader 擴(kuò)展類加載器

負(fù)責(zé)JRE的擴(kuò)展目錄中jar包的加載疤孕。

在JDK中JRE的lib目錄下ext目錄

SysetmClassLoader 系統(tǒng)類加載器

負(fù)責(zé)在JVM啟動(dòng)時(shí)加載來自java命令的class文件商乎,以及classpath環(huán)境變量所指定的jar包和類路徑

AppClassLoader 加載其他類

負(fù)載一些非核心類和程序猿自己寫的類

演示

publicstaticvoidmain(String[]args) {

? ? //獲取TestDemo類的類加載器

? ? System.out.println(TestDemo.class.getClassLoader());


}

五. 自定義類加載器

雙親委派模型

當(dāng)前類加載器從自己已經(jīng)加載的類中查詢是否此類已經(jīng)加載,如果已經(jīng)加載則直接返回原來已經(jīng)加載的類祭阀。

如果沒有找到鹉戚,就去委托父類加載器去加載(如代碼c = parent.loadClass(name, false)所示)。父類加載器也會(huì)采用同樣的策略专控,查看自己已經(jīng)加載過的類中是否包含這個(gè)類抹凳,有就返回,沒有就委托父類的父類去加載伦腐,一直到根類加載器赢底。因?yàn)槿绻讣虞d器為空了,就代表使用根類類加載器作為父加載器去加載

如果根類類加載器加載失敯啬ⅰ(例如在$JAVA_HOME/jre/lib里未查找到該class)幸冻,會(huì)使用拓展類加載器來嘗試加載,繼續(xù)失敗則會(huì)使用AppClassLoader來加載辩越,繼續(xù)失敗則會(huì)拋出一個(gè)異常ClassNotFoundException嘁扼,然后再調(diào)用當(dāng)前加載器的findClass()方法進(jìn)行加載

好處

主要是為了安全性,避免用戶自己編寫的類動(dòng)態(tài)替換 Java的一些核心類黔攒,比如 String趁啸。

同時(shí)也避免了類的重復(fù)加載,因?yàn)?JVM中區(qū)分不同類督惰,不僅僅是根據(jù)類名不傅,相同的 class文件被不同的 ClassLoader加載就是不同的兩個(gè)類

案例演示

publicclassMyClassLoaderextendsClassLoader{

? ? privateStringpath;

? ? publicMyClassLoader(Stringpath) {

? ? ? ? super();

? ? ? ? this.path=path;

? ? }

? ? @Override

? ? protectedClass<?>findClass(Stringname)throwsClassNotFoundException{

? ? ? ? //讀取本地文件

? ? ? ? byte[]bs=getBytes(path);

? ? ? ? //將字節(jié)數(shù)組裝載成Class對(duì)象

? ? ? ? Class<?>clazz=this.defineClass(name,bs,0,bs.length);

? ? ? ? returnclazz;

? ? }


? ? privatebyte[]getBytes(Stringpath){

? ? ? ? try(

? ? ? ? ? ? FileInputStreamfis=newFileInputStream(path);

? ? ? ? ? ? ByteArrayOutputStreambos=newByteArrayOutputStream();

? ? ? ? ) {

? ? ? ? ? ? byte[]bs=newbyte[1024];

? ? ? ? ? ? intlen;

? ? ? ? ? ? while((len=fis.read(bs))!=-1){

? ? ? ? ? ? ? ? bos.write(bs,0,len);

? ? ? ? ? ? }

? ? ? ? ? ? returnbos.toByteArray();

? ? ? ? }catch(Exceptione) {


? ? ? ? }

? ? ? ? returnnull;

? ? }

}

publicstaticvoidmain(String[]args)throwsException{

? ? MyClassLoaderclassLoader=newMyClassLoader("D:\\Student.class");

? ? Class<?>clazz=classLoader.findClass("com.qianfeng.Student");

? ? //Class<?> class1 = Class.forName("com.qianfeng.Student", true, classLoader);


? ? Objectobj=clazz.newInstance();

? ? System.out.println(obj.getClass().getClassLoader());

}

六. 反射

定義

JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類赏胚,都能夠知道這個(gè)類的所有屬性和方法

對(duì)于任意一個(gè)對(duì)象访娶,都能夠調(diào)用它的任意一個(gè)方法和屬性

這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語言的反射機(jī)制

要想解剖一個(gè)類,必須先要獲取到該類的字節(jié)碼文件對(duì)象

而解剖使用的就是Class類中的方法,所以先要獲取到每一個(gè)字節(jié)碼文件對(duì)應(yīng)的Class類型的對(duì)象

說白了就是獲取一個(gè)類的骨架

獲取字節(jié)碼的三種方式

對(duì)象.getClass()

類名.class

Class類中靜態(tài)方法forName("類名")

演示

publicstaticvoidmain(String[]args)throwsException{

? ? Studentstudent=newStudent();

? ? Class<?>clazz1=student.getClass();

? ? Class<?>clazz2=Student.class;

? ? Class<?>clazz3=Class.forName("com.qianfeng.Student");

}

七. 反射獲取構(gòu)造函數(shù)

定義

Class類的newInstance()方法是使用該類無參的構(gòu)造函數(shù)創(chuàng)建對(duì)象

如果一個(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)建對(duì)象

演示

publicstaticvoidmain(String[]args)throwsException{

? ? Class<?>clazz=Class.forName("com.qianfeng.Student");

? ? Studentobject=(Student)clazz.newInstance();

? ? object.method();


}

榨汁機(jī)案例

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

根據(jù)客戶的需求, 隨時(shí)更換果汁

interfaceFruit{

? ? publicvoidsqueeze();

}

?

classAppleimplementsFruit{

? ? publicvoidsqueeze() {

? ? ? ? System.out.println("榨出一杯蘋果汁兒");

? ? }

}

?

classOrangeimplementsFruit{

? ? publicvoidsqueeze() {

? ? ? ? System.out.println("榨出一杯桔子汁兒");

? ? }

}

?

classJuicer{

? ? publicvoidrun(Fruitf) {

? ? ? ? f.squeeze();

? ? }

?

}

publicstaticvoidmain(String[]args)throwsException{


? ? //從本地讀取配置文件

? ? BufferedReaderbr=newBufferedReader(newFileReader("config.txt"));

//創(chuàng)建輸入流對(duì)象,關(guān)聯(lián)配置文件?

? ? Class<?>clazz=Class.forName(br.readLine());? //讀取配置文件一行內(nèi)容,獲取該類的字節(jié)碼對(duì)象

? ? Fruitf=(Fruit)clazz.newInstance();? ? ? //通過字節(jié)碼對(duì)象創(chuàng)建實(shí)例對(duì)象

? ? Juicerj=newJuicer();

? ? j.run(f);

}

八. 反射獲取成員變量

定義

Class.getField(String)方法可以獲取類中的指定字段(可見的)

如果是私有的可以用getDeclaedField("name")方法獲取

通過get(obj) 和set(obj, "李四")方法可以獲取和設(shè)置指定對(duì)象上該字段的值, obj指的是這個(gè)類的對(duì)象

如果是私有的需要先調(diào)用setAccessible(true)設(shè)置訪問權(quán)限放開

演示

publicstaticvoidmain(String[]args)throwsException{

? ? Studentstudent=newStudent();

? ? Class<?>clazz=Class.forName("com.qianfeng.Student");

? //獲取共有的屬性

? ? Fieldfield=clazz.getField("name");

? //獲取所有的屬性

? ? Fieldfield2=clazz.getDeclaredField("name");

? ? //取消語言檢查

? ? field2.setAccessible(true);

? ? //給一個(gè)對(duì)象的屬性設(shè)置值

? ? field2.set(student,"333");

? ? //獲取這個(gè)對(duì)象的屬性的值

? ? Stringstr=(String)field2.get(student);

? ? System.out.println(str);


}

測試題

需求: 寫一個(gè)方法, 通過此方法可以給任意對(duì)象的任意屬性設(shè)置值

九. 反射獲取成員方法

定義

Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以獲取類中的指定方法

調(diào)用invoke(Object, Object...)可以調(diào)用對(duì)象的這個(gè)方法

演示

publicstaticvoidmain(String[]args)throwsException{

? ? Studentstudent=newStudent();

? ? Class<?>clazz=Class.forName("com.qianfeng.Student");

? ? Methodmethod=clazz.getMethod("method");

? ? method.invoke(student);

? ? //獲取私有方法

? ? Methodmethod2=clazz.getDeclaredMethod("method2");

? ? //取消語言檢查

? ? method2.setAccessible(true);

? ? //調(diào)用對(duì)象的方法

? ? method2.invoke(student);


}

測試題

需求: 往一個(gè)ArrayList<Integer> 的對(duì)象中添加String類型的值

十. 動(dòng)態(tài)代理

定義

代理: 本來應(yīng)該自己做的事情觉阅,請(qǐng)了別人來做崖疤,被請(qǐng)的人就是代理對(duì)象

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

代理可以使我們?cè)诓黄茐脑创a的情況下增加新的功能

java中動(dòng)態(tài)代理的使用

在Java中java.lang.reflect包下提供了一個(gè)Proxy類和一個(gè)InvocationHandler接口劫哼,通過使用這個(gè)類和接口就可以生成動(dòng)態(tài)代理對(duì)象

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

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

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

演示

publicstaticvoidmain(String[]args)throwsException{


? ? Studentstudent=newStudent();

? ? //創(chuàng)建Student的代理對(duì)象

? ? MyInterfacep=(MyInterface)Proxy.newProxyInstance(Student.class.getClassLoader(),Student.class.getInterfaces(),newInvocationHandler() {


? ? ? ? @Override

? ? ? ? publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{

? ? ? ? ? ? System.out.println("你好");

? ? ? ? ? ? method.invoke(student);

? ? ? ? ? ? returnnull;

? ? ? ? }

? ? });

? ? p.method();

}

原理

利用對(duì)象的類的字節(jié)碼接口,寫出一個(gè)新的類到本地區(qū),通過編譯器直接編譯成.class文件,再通過類加載器加載進(jìn)來

弊端: 代理的對(duì)象必須實(shí)現(xiàn)接口

十一. cglib

定義

非java原生的動(dòng)態(tài)代理, 效率更高,限制更小

可以代理沒有接口的類

使用

導(dǎo)包

演示

publicstaticvoidmain(String[]args) {

? ? //導(dǎo)入包? cglib-core? asm? ? ant? ? ant-launcher

? ? //創(chuàng)建運(yùn)行器

? ? MethodInterceptormi=newMethodInterceptor() {


? ? ? ? @Override

? ? ? ? publicObjectintercept(Objectarg0,Methodarg1,Object[]arg2,MethodProxyarg3)throwsThrowable{

? ? ? ? ? ? System.out.println("運(yùn)行前");

? ? ? ? ? ? arg3.invokeSuper(arg0,arg2);

? ? ? ? ? ? System.out.println("運(yùn)行后");

? ? ? ? ? ? returnnull;

? ? ? ? }

? ? };

? ? //獲取代理類

? ? Enhancerenhancer=newEnhancer();

? ? //設(shè)置父類

? ? enhancer.setSuperclass(Demo.class);

? ? //運(yùn)行任務(wù)

? ? enhancer.setCallback(mi);

? ? //創(chuàng)建代理對(duì)象

? ? Demod=(Demo)enhancer.create();

? ? d.method();

}

總結(jié)

單例模式

模式: 針對(duì)某種問題的最優(yōu)解

懶漢式, 餓漢式 , 餓漢式的變形體

如何寫單例模式

私有化構(gòu)造方法

提供自己創(chuàng)建的對(duì)象給使用者

優(yōu)點(diǎn) :

節(jié)省內(nèi)存空間,? 提升訪問的速度

缺點(diǎn) :

相對(duì)于靜態(tài)來說, 效率還是要低一些

枚舉

枚舉就是多例的簡寫形式

枚舉項(xiàng)的權(quán)限, 修飾符, 類型, new 省略

枚舉的注意事項(xiàng)

類加載

就是將.class文件從硬盤上讀取到內(nèi)存中,變成一個(gè)java可以使用的類

類加載器

四個(gè)類加載器和他們的應(yīng)用范圍

根類加載器不是java代碼寫的

雙親委派模型

加載一個(gè)類的時(shí)候,從最底層的類加載器開始逐層上傳, 一直到頂層, 整個(gè)過程要檢測這個(gè)類有沒有被加載過

作用 : 保持類的唯一性

反射

反射其實(shí)就是java提供的另外一種編程模式

提高了代碼的兼容性, 擴(kuò)展性

反射操作構(gòu)造方法, 操作成員變量, 操作成員方法

作業(yè)

把今天的案例都敲一遍

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市割笙,隨后出現(xiàn)的幾起案子权烧,更是在濱河造成了極大的恐慌眯亦,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件般码,死亡現(xiàn)場離奇詭異妻率,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)板祝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門宫静,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人券时,你說我怎么就攤上這事囊嘉。” “怎么了革为?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長舵鳞。 經(jīng)常有香客問我震檩,道長,這世上最難降的妖魔是什么蜓堕? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任抛虏,我火速辦了婚禮,結(jié)果婚禮上套才,老公的妹妹穿的比我還像新娘迂猴。我一直安慰自己,他們只是感情好背伴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布沸毁。 她就那樣靜靜地躺著,像睡著了一般傻寂。 火紅的嫁衣襯著肌膚如雪息尺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天疾掰,我揣著相機(jī)與錄音搂誉,去河邊找鬼。 笑死静檬,一個(gè)胖子當(dāng)著我的面吹牛炭懊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拂檩,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼侮腹,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了广恢?” 一聲冷哼從身側(cè)響起凯旋,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后至非,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钠署,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年荒椭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谐鼎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡趣惠,死狀恐怖狸棍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情味悄,我是刑警寧澤草戈,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站侍瑟,受9級(jí)特大地震影響唐片,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜涨颜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一费韭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庭瑰,春花似錦星持、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至穷吮,卻和暖如春损痰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背酒来。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國打工卢未, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人堰汉。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓辽社,卻偏偏與公主長得像,于是被迫代替她去往敵國和親翘鸭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子滴铅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355