Java基礎(chǔ)

1. ==和equals有什么區(qū)別:從基本數(shù)據(jù)類型和引用數(shù)據(jù)類型的不同來回答

  1. ==
    1. 基本數(shù)據(jù)類型比較值
    2. 引用數(shù)據(jù)類型比較內(nèi)存地址
  2. equals
    1. 基本數(shù)據(jù)類型不能使用equals
    2. 引用數(shù)據(jù)類型如果沒有重寫,比較值

2. hashcode方法做了什么,為什么重寫equals必須要重寫hashcode:因?yàn)橐WCequals為true的同時(shí)hashcode也要相同,舉例hashMap存儲(chǔ)

  1. hashcode會(huì)返回調(diào)用者的hash值,一般來說hashcode會(huì)和equals一起使用,比如hashMap就是通過hashcode和equals來判斷key是否重復(fù)。兩個(gè)hashcode相同的對(duì)象,equals不一定為true。而equals為true的兩個(gè)對(duì)象,其hashcode必須要相同。
  2. 比如hashMap的put方法,會(huì)在遍歷鏈表的同時(shí),通過equals和hashcode判斷key是否重復(fù),如果重復(fù),進(jìn)行替換。如果equals為true但是hashcode不相同,可能會(huì)造成key重復(fù)存儲(chǔ),違反了hashMap的key不重復(fù)原則。

3. 深拷貝和淺拷貝,Arraycopy和System.arraycopy

  1. 深拷貝:值傳遞,創(chuàng)建一個(gè)新對(duì)象存放基本數(shù)據(jù)類型和引用數(shù)據(jù)類型,修改一個(gè)不會(huì)影響另一個(gè)
  2. 淺拷貝:引用傳遞,只復(fù)制了基本數(shù)據(jù)類型和引用變量,引用指向沒有復(fù)制,修改引用數(shù)據(jù)類型可能會(huì)影響原對(duì)象。
  3. Arrays.copyOf():創(chuàng)建一個(gè)新數(shù)組存放,然后調(diào)用System.arraycopy()進(jìn)行復(fù)制。會(huì)修改原數(shù)組
  4. System.arraycopy():只拷貝已存在的數(shù)組元素,不會(huì)修改元素

4. 基本數(shù)據(jù)類型和引用數(shù)據(jù)類型:

  1. int,32位4字節(jié)
  2. byte,8位1字節(jié)
  3. char,16位2字節(jié)
  4. short,16位2字節(jié)
  5. long,64位8字節(jié)
  6. float,32位4字節(jié)
  7. double,64位8字節(jié)
  8. boolean,1位,0和1。
  9. 引用數(shù)據(jù)類型:包裝類、String、數(shù)組、對(duì)象

5. 包裝類的拆包和裝包:int轉(zhuǎn)Integer裝包,Integer轉(zhuǎn)int拆包

  1. 裝包:Integer int1 = 1; //調(diào)用Integer.valueOf(1)
  2. 拆包:int int2 = new Integer(1) //拆包,調(diào)用int2.intValue()

6. Integer和int的==判斷:Integer、int和緩存池比較

  1. Integer i1 = new Integer(123)和Iteger i2 = 123的區(qū)別
    1. new Integer(123)會(huì)在堆中分配空間創(chuàng)建123的Integer對(duì)象,每次都會(huì)創(chuàng)建一個(gè)不同內(nèi)存地址的對(duì)象。
    2. 而i2 = 123會(huì)先查看包裝類緩存池中是否存在123的Integer,如果有,i2變量名指向它。如果沒有,新建一個(gè)123放入到緩存池中,然后i2變量名指向它。
    3. i1 == i2,返回false
  2. int和Integer的==判斷
int int1 = 12;
int int2 = 12;

Integer integer1 = 12;
Integer integer2 = 12;

Integer i1 = 12;
Integer i2 = 128;
Integer i3 = 128;

int1 == int2;       //true,基本數(shù)據(jù)類型,==比較值

int1 = integer1;        //true,Integer拆箱,integer1.intValue(),基本數(shù)據(jù)類型,==比較值

integer1 == integer2;   //false,堆中的兩個(gè)不同對(duì)象,==比較內(nèi)存地址

integer1 == i1;     //false,integer1是堆中的,i1是包裝類緩存池中的,不同的內(nèi)存地址

i2 == i3;       //false,Integer的范圍-128~127,超出范圍
  1. Integer與int比較時(shí),調(diào)用intValue()拆箱
  2. Integer范圍-128~127

7. String、StringBuilder(初始容量16)、StringBuffer比較:可變、運(yùn)行速度、線程安全、使用場(chǎng)景來講

  1. String是final類,是不可變的,線程安全,每次拼接都要?jiǎng)?chuàng)建一個(gè)新的對(duì)象來接收拼接后的字符串。效率低
  2. StringBuilder和StringBuffer可以通過append方法來拼接。效率高
  3. 運(yùn)行速度:StringBuilder、StringBuffer、String
  4. 線程安全:StringBuffer的append方法用synchronized修飾
  5. 使用場(chǎng)景
    1. 單線程操作少:String
    2. 單線程數(shù)據(jù)量大:StringBuilder
    3. 多線程數(shù)據(jù)量大:StringBuffer

8. 字符串常量池:為什么要使用和如何使用

  1. 減少相同字符串的創(chuàng)建,節(jié)省空間
  2. String s1 = "123";

9. String s1 = "123"和String s2 = new String("123")的內(nèi)存分析、String s2 = new String("123")創(chuàng)建了幾個(gè)String對(duì)象

  1. String s1 = "123"時(shí),先在棧中創(chuàng)建一個(gè)s1變量名,然后查看字符串緩存池中是否存在"123"字符串,如果有,s1變量名指向它,如果沒有,創(chuàng)建一個(gè)"123"字符串放入緩存池,然后s1變量名指向它。
  2. String s2 = new String("123")時(shí),先在棧中創(chuàng)建一個(gè)s2變量名,然后在堆中創(chuàng)建一個(gè)"123"的字符串對(duì)象,s2變量名指向它。
  3. s1 == s2; //false,引用數(shù)據(jù)類型,==比較內(nèi)存地址,不相同
  4. s1在字符串緩存池創(chuàng)建了一個(gè)"123"字符串對(duì)象
  5. s2在堆中創(chuàng)建了一個(gè)"123"字符串對(duì)象

10. static關(guān)鍵字用法:修飾內(nèi)部類、修飾方法、修飾變量、修飾代碼塊、全局變量和靜態(tài)變量的區(qū)別

  1. 修飾內(nèi)部類(不可繼承):可以通過外部類.內(nèi)部類
  2. 修飾方法:類名.方法名
  3. 修飾變量:類名.變量名,只加載一次,也就是內(nèi)存中只存在一份副本。修改后的值就是最新值
  4. 修飾代碼塊:類加載時(shí)被執(zhí)行,只執(zhí)行一次
  5. 全局變量和靜態(tài)變量
    1. 全局隨著對(duì)象,靜態(tài)隨著類
    2. 全局只能被對(duì)象調(diào)用,靜態(tài)可以被對(duì)象和類調(diào)用
    3. 全局變量在jvm的堆中,靜態(tài)變量在jvm的方法區(qū)

11. 父子類加載過程

  1. 父類靜態(tài)變量、父類靜態(tài)代碼塊
  2. 子類靜態(tài)變量、子類靜態(tài)代碼塊
  3. 父類全局變量、父類全局代碼塊、父類構(gòu)造
  4. 子類全局變量、子類全局代碼塊、子類構(gòu)造

12. final關(guān)鍵字用法:修飾類、修飾方法、修飾變量、好處

  1. 修飾類:不可被繼承
  2. 修飾方法:不可被重寫
  3. 修飾變量:常量,一般與static連用,必須賦初值,不可修改。類常量存放在jvm方法區(qū)的常量池中。常量池1.6之前在方法區(qū),1.7在堆,1.8在元空間
  4. 好處:
    1. 多線程下線程安全
    2. 常量池可以減少重復(fù)創(chuàng)建常量,減少內(nèi)存開銷
  5. final、finally、finalized
    1. final修飾符
    2. finally關(guān)鍵字,最終必定會(huì)執(zhí)行代碼塊
    3. finalized是gc回收的前置工作

13. super和this的用法:this不能用于靜態(tài)方法

  1. super用于調(diào)用父類的同名變量、同名方法、調(diào)用父類構(gòu)造
  2. this訪問子類的同名變量或者指代當(dāng)前對(duì)象
  3. this不能用于靜態(tài)方法。因?yàn)殪o態(tài)方法是隨類加載而被加載的,而this指代的是調(diào)用靜態(tài)方法的對(duì)象,但是靜態(tài)方法加載時(shí),調(diào)用對(duì)象還不一定存在。

14. 權(quán)限控制符:private、default、protected、public

  1. private當(dāng)前類
  2. default當(dāng)前包
  3. protected當(dāng)前包和子類
  4. public所用

15. 三大特征:封裝(實(shí)體類)、繼承、多態(tài)

  1. 封裝:將屬性和方法寫在一個(gè)類中。如實(shí)體類
  2. 繼承:子類可以繼承父類的非私有屬性和方法。但不能繼承父類的構(gòu)造函數(shù),僅可以通過super調(diào)用。java只支持單繼承,一個(gè)子類只能有一個(gè)父類,一個(gè)父類可以有多個(gè)子類
  3. 多態(tài)
    1. 實(shí)現(xiàn)前提:繼承或?qū)崿F(xiàn)接口
    2. 表現(xiàn)形式:父類引用可以指向子類對(duì)象和接口引用指向?qū)崿F(xiàn)類對(duì)象
    3. 編譯時(shí)多態(tài):重載,重載方法可以通過參數(shù)個(gè)數(shù)和參數(shù)類型在編譯時(shí)就確定調(diào)用哪一個(gè)方法
    4. 運(yùn)行時(shí)多態(tài):重寫,重寫方法僅方法實(shí)現(xiàn)不同,編譯時(shí)無法確定調(diào)用哪一個(gè)方法,只能在運(yùn)行時(shí)從子類往上搜索

16. 重載和重寫的區(qū)別

  1. 重載:參數(shù)類型和參數(shù)個(gè)數(shù)不同
  2. 重寫:方法具體實(shí)現(xiàn)不同,子類權(quán)限必須大于父類
  3. 構(gòu)造函數(shù)無法重寫,但可以重載

17. 抽象類:定義、實(shí)現(xiàn)方式、構(gòu)造函數(shù)、變量、方法、單繼承

  1. 定義:使用abstract定義,extends繼承,不能用private修飾
  2. 實(shí)現(xiàn):子類必須重寫抽象類的所有抽象方法
  3. 構(gòu)造函數(shù):抽象類可以有構(gòu)造函數(shù),但不能實(shí)例化
  4. 方法:抽象方法不能用private,可以有普通方法
  5. 變量:權(quán)限無要求

18. 接口:定義、實(shí)現(xiàn)方式、構(gòu)造函數(shù)、變量、方法、多繼承

  1. 定義:使用interface定義,implements實(shí)現(xiàn),嵌套接口可以用private
  2. 實(shí)現(xiàn):實(shí)現(xiàn)類必須重寫接口所有非默認(rèn)方法
  3. 構(gòu)造函數(shù):接口沒有構(gòu)造函數(shù)
  4. 方法:接口方法不能用private修飾,默認(rèn)都是抽象方法
  5. 變量:默認(rèn)是static final,必須賦初值

19. 抽象類和接口的區(qū)別:多繼承、實(shí)現(xiàn)方式、構(gòu)造函數(shù)、變量、方法、使用優(yōu)先

  1. 多繼承:抽象類只能實(shí)現(xiàn)單繼承,接口可以實(shí)現(xiàn)多繼承
  2. 實(shí)現(xiàn):子類和實(shí)現(xiàn)類都必須重寫方法
  3. 構(gòu)造函數(shù):接口沒有構(gòu)造函數(shù),抽象類有
  4. 方法:接口方法默認(rèn)是抽象方法,不能用private
  5. 變量:接口變量默認(rèn)是static final,必須賦初值,且權(quán)限范圍無要求
  6. 優(yōu)先考慮使用接口

20. 各種變量在JVM中的位置:靜態(tài)變量、局部變量(方法內(nèi))、全局變量(類中)

  1. 靜態(tài)變量:jvm方法區(qū)
  2. 全局變量(類中方法外):無論是基本還是引用,都在堆中
  3. 局部變量(類中方法中):基本的變量名和值都在棧(局部變量表)。引用的變量名在棧(局部變量表),值在堆中

21. 多態(tài):表現(xiàn)、好處、前提、運(yùn)行時(shí)多態(tài)(重寫)、編譯時(shí)多態(tài)(重載)

  1. 表現(xiàn):父類引用指向子類對(duì)象或者接口引用指向?qū)崿F(xiàn)類的對(duì)象,從而可以訪問他們的屬性和方法2. 多態(tài)前提:繼承和實(shí)現(xiàn)接口
  2. 好處:代碼拓展性好
  3. 編譯時(shí)多態(tài):重載,編譯時(shí)根據(jù)參數(shù)類型和參數(shù)個(gè)數(shù)確定調(diào)用哪個(gè)方法
  4. 運(yùn)行時(shí)多態(tài):重寫,重寫僅方法實(shí)現(xiàn)不同,編譯時(shí)無法確定,運(yùn)行時(shí)從子類開始往上找

22. 注解和反射:元注解、自定義注解、反射的含義、獲取class實(shí)例的三種方式

  1. 元注解
    1. Target:value=Element.TYPE、METHOD
    2. Rentention:value=RententionPolicy.RUNTIME
    3. Document
  2. 自定義一個(gè)注解
1. 定義注解
@Target(value = Element.METHOD)
@Rentention(value = RententionPolicy.RUNTIME)
public @interface MyAnnotation{
    String name() default "123";
    int age();
}

2. 使用注解
public class Test{
    @MyAnnotation(age = 18)
    public void Test(){}
}
  1. 反射:當(dāng)編譯一個(gè)類之后,會(huì)產(chǎn)生一個(gè).class文件,該文件內(nèi)存放著class對(duì)象。類加載相當(dāng)于class對(duì)象的加載,而反射可以在運(yùn)行時(shí)通過.class字節(jié)碼問題件生成類并實(shí)現(xiàn)對(duì)象的增強(qiáng)
  2. java.lang.reflect包提供了三個(gè)類
    1. Field:變量級(jí)別,get和set
    2. Method:方法級(jí)別,invoke進(jìn)行增強(qiáng)
    3. Constructor:構(gòu)造函數(shù)級(jí)別,newInstance創(chuàng)建實(shí)例
  3. 獲取class對(duì)象的三種方法
    1. Class class = User.class
    2. Class class = User.getClass().getName();
    3. Classs class = Class.forName("...");可能出現(xiàn)路徑異常

23. 異常:error和exception(受檢和非受檢)

  1. error是jvm錯(cuò)誤
  2. exception是異常,分為受檢異常和非受檢異常
    1. 受檢異常:try/catch
    2. 非受檢異常:運(yùn)行時(shí)發(fā)生異常
  3. try、catch、finally的執(zhí)行順序
    1. 如果沒有異常,沒有return。try和finally
    2. 如果有異常,沒有return。try、catch、finally
    3. 如果有return,return返回所在模塊的計(jì)算結(jié)果
//1. try中return
    private int testReturn1() {
        int i = 1;
        try {
            i++;
            System.out.println("try:" + i);
            return i;
        } catch (Exception e) {
            i++;
            System.out.println("catch:" + i);
        } finally {
            i++;
            System.out.println("finally:" + i);
        }
        return i;
    }
//輸出
try:2
finally:3
2

//2. catch中return
    private int testReturn3() {
        int i = 1;
        try {
            i++;
            System.out.println("try:" + i);
            int x = i / 0 ;
        } catch (Exception e) {
            i++;
            System.out.println("catch:" + i);
            return i;
        } finally {
            i++;
            System.out.println("finally:" + i);
        }
        return i;
    }
//輸出
try:2
catch:3
finally:4
3

//3. finally中return
    private int testReturn4() {
        int i = 1;
        try {
            i++;
            System.out.println("try:" + i);
            return i;
        } catch (Exception e) {
            i++;
            System.out.println("catch:" + i);
            return i;
        } finally {
            i++;
            System.out.println("finally:" + i);
            return i;
        }
    }
//輸出
try:2
finally:3
3

24. Linux內(nèi)核IO模型

  1. 阻塞io:對(duì)應(yīng)java中的bio,讀寫阻塞,線程發(fā)出io請(qǐng)求后,內(nèi)核查看數(shù)據(jù)是否就緒,未就緒就阻塞,等到就緒之后,內(nèi)核將數(shù)據(jù)拷貝到用戶線程。返回結(jié)果給用戶線程
  2. 非阻塞io:用戶線程發(fā)起io請(qǐng)求后,先不等待結(jié)果,內(nèi)核輪詢查看數(shù)據(jù),當(dāng)數(shù)據(jù)就緒之后,將數(shù)據(jù)拷貝到用戶線程并通知用戶線程
  3. 多路復(fù)用io:對(duì)應(yīng)java中的nio,selector線程不斷輪詢socket,當(dāng)socket有連接時(shí)通知線程進(jìn)行io。單線程管理多個(gè)socket,只關(guān)心活躍的socket連接。
  4. 信號(hào)驅(qū)動(dòng)io:用戶線程發(fā)起io請(qǐng)求后,socket注冊(cè)一個(gè)信號(hào)函數(shù),當(dāng)數(shù)據(jù)就緒時(shí),內(nèi)核通知用戶線程進(jìn)行io操作
  5. 異步io:對(duì)應(yīng)java中的Aio,用戶線程只需要發(fā)起io請(qǐng)求,數(shù)據(jù)的拷貝交給內(nèi)核完成,線程完全不阻塞

25. Java IO模型:同步和異步、BIO、NIO、AIO

  1. 同步異步、阻塞非阻塞
    1. 同步阻塞:線程發(fā)起io請(qǐng)求后需要等待結(jié)果才能繼續(xù)執(zhí)行
    2. 異步非阻塞:線程發(fā)起io請(qǐng)求后就可以執(zhí)行其他操作,內(nèi)核通過回調(diào)函數(shù)方式通知線程
  2. BIO:同步阻塞,一個(gè)socket對(duì)應(yīng)一個(gè)線程,讀寫時(shí)線程被阻塞,無法進(jìn)行其他操作
    1. 傳統(tǒng)單線程模式,acceptor線程通過while true循環(huán)調(diào)用accept方法監(jiān)聽連接請(qǐng)求。一個(gè)socket對(duì)應(yīng)一個(gè)線程,io時(shí)線程被阻塞,必須先完成一個(gè)請(qǐng)求才能繼續(xù)執(zhí)行下一個(gè)請(qǐng)求
    2. 偽異步多線程模式:服務(wù)器通過線程池接收連接請(qǐng)求
    3. 特點(diǎn):
      1. 同步阻塞,一個(gè)線程一個(gè)連接?;诹?/li>
  3. NIO:同步非阻塞,同步指的是一個(gè)線程對(duì)應(yīng)一個(gè)連接,非阻塞指的是selector多路復(fù)用器分發(fā)連接請(qǐng)求,channel是雙向的
    1. selector:多路復(fù)用器,輪詢監(jiān)聽多個(gè)channel的狀態(tài),基于buffer,可以同時(shí)進(jìn)行讀寫。沒有連接時(shí)會(huì)發(fā)生阻塞
    2. channel:雙向通道,連接buffer
    3. buffer:緩沖區(qū),數(shù)據(jù)的中轉(zhuǎn)站
    4. 特點(diǎn)
      1. 同步:線程進(jìn)行io時(shí)必須先完成一個(gè)請(qǐng)求才能繼續(xù)下一個(gè)請(qǐng)求
      2. 非阻塞:selector多路復(fù)用器監(jiān)聽多個(gè)channel
  4. AIO:異步非阻塞,基于回調(diào)函數(shù)實(shí)現(xiàn),線程只管發(fā)起請(qǐng)求,后續(xù)操作由內(nèi)核完成,內(nèi)核通過回調(diào)函數(shù)通知線程

26. select、poll、epoll

  1. select:監(jiān)聽一組fd_set,等待一個(gè)或多個(gè)fd成為就緒狀態(tài),完io
    1. 數(shù)據(jù)結(jié)構(gòu):數(shù)組,大小1024或2048
    2. 類型:read、write、except
    3. timeout超時(shí)函數(shù)
    4. 成功返回大于0,失敗返回-1,超時(shí)返回0
  2. poll:監(jiān)聽一組pollfd
    1. 數(shù)據(jù)結(jié)構(gòu):數(shù)據(jù),大小無上限
    2. 類型:多種pollfd
    3. timeout超時(shí)函數(shù)
    4. 成功返回大于0,失敗返回-1,超時(shí)返回0
  3. epoll:注冊(cè)fd_set,通過紅黑樹維護(hù),回調(diào)函數(shù)通知線程
    1. 數(shù)據(jù)結(jié)構(gòu):紅黑樹
    2. 工作模式:LT水平、ET邊緣
    3. LT:當(dāng)epoll_wait檢查到fd就緒時(shí),通知線程,可以等到下一次觸發(fā)時(shí)才處理。默認(rèn)模式,阻塞和非阻塞
    4. ET:通知線程后必須馬上執(zhí)行,效率高,非阻塞
  4. 總結(jié)
    1. select
      1. 實(shí)現(xiàn)方式:遍歷fd_set
      2. 數(shù)據(jù)結(jié)構(gòu):數(shù)組
      3. 時(shí)間復(fù)雜度:On
      4. 最大連接上限:1024,2048
      5. 使用場(chǎng)景:實(shí)時(shí)性好、移植性好
    2. poll
      1. 實(shí)現(xiàn)方式:遍歷pollfd
      2. 數(shù)據(jù)結(jié)構(gòu):數(shù)組
      3. 時(shí)間復(fù)雜度:On
      4. 最大連接上限:無上限
      5. 使用場(chǎng)景:實(shí)時(shí)性要求不高
    3. epoll
      1. 實(shí)現(xiàn)方式:回調(diào)函數(shù)
      2. 數(shù)據(jù)結(jié)構(gòu):紅黑樹
      3. 時(shí)間復(fù)雜度:O1
      4. 最大連接上限:無上限
      5. 使用場(chǎng)景:Linux系統(tǒng),長(zhǎng)連接

26. 設(shè)計(jì)模式:?jiǎn)卫?、工廠、代理、手撕?jiǎn)卫秃?jiǎn)單工廠

1. 單例模式

  1. 用于封裝工具類,使整個(gè)系統(tǒng)的數(shù)據(jù)統(tǒng)一。SpringBean的作用域singleTon用到了單例模式
  2. 特征:唯一實(shí)例、唯一構(gòu)造、自己創(chuàng)建實(shí)例
  3. 餓漢模式:線程安全,類加載就創(chuàng)建實(shí)例,可能造成內(nèi)存浪費(fèi),不適合創(chuàng)建大對(duì)象
public class Hungry{
    private static Hungry hungry = new Hungry();
    private static Hungry(){};
    public static Hungry getInstance(){
        return hungry;
    }
}
  1. 懶漢模式:線程不安全,調(diào)用時(shí)才創(chuàng)建實(shí)例
public class Lazy{
    private static Lazy lazy = null;
    private static Lazy(){};
    public static Lazy getInstance(){
        if(lazy == null){
            lazy = new Lazy();
        }
        return lazy;
    }
}
  1. 雙重檢查:synchronized線程安全,volatile保證構(gòu)造函數(shù)4指令不重排序
public class Double{
    private static Double double = null;
    /*
    1. 申請(qǐng)空間
    2. 初始化默認(rèn)值
    3. 執(zhí)行構(gòu)造
    4. 連接引用
    */
    private static volatile Double(){};
    public static Double getInstance(){
        //第一層null判斷:減少進(jìn)入synchronized代碼塊,提高性能。
        if(double == null){
            synchronized(Double.class){
                //第二層null判斷:避免創(chuàng)建重復(fù)單例
                if(double == null){
                    double = new Double();
                }
            }
        }
        return double;
    }
}

2. 工廠模式

  1. 創(chuàng)建者和調(diào)用者分類,如果創(chuàng)建對(duì)象時(shí)有重復(fù)代碼,可以考慮使用工廠類創(chuàng)建
  2. SpringIOC的BeanFactory用到了工廠模式
  3. 簡(jiǎn)單工廠模式
public interface Car{
    public void getName();
}

public class Wuling implements Car{
    public void getName(){
        System.out.println("五菱");
    }
}

public class Factory{
    public static Car getCarName(String name){
        if(name.equals("五菱")){
            return new Wuling();
        }
    }
}

public static void main(String[] args){
    Car car = Factory.getCarName("五菱");
    car.getName();  //輸出五菱
}

3. 代理模式

  1. 三個(gè)對(duì)象
    1. 抽象對(duì)象:通過接口或抽象類定義真實(shí)對(duì)象需要實(shí)現(xiàn)的行為
    2. 代理對(duì)象:實(shí)現(xiàn)抽象對(duì)象,重寫抽象對(duì)象的方法,提供具體實(shí)現(xiàn)給真實(shí)對(duì)象
    3. 真實(shí)對(duì)象:實(shí)現(xiàn)抽象對(duì)象,調(diào)用代理對(duì)象提供的方法實(shí)現(xiàn)抽象方法。
  2. 靜態(tài)代理:手動(dòng)編寫的代理關(guān)系
  3. 動(dòng)態(tài)代理:運(yùn)行時(shí)由反射重寫
  4. SpringAOP用到了動(dòng)態(tài)代理
    1. 代理對(duì)象是實(shí)現(xiàn)類,使用jdk動(dòng)態(tài)代理,重組字節(jié)碼文件,由反射機(jī)制生成一個(gè)接口實(shí)現(xiàn)類
    2. 代理對(duì)象不是實(shí)現(xiàn)類,使用cglib動(dòng)態(tài)代理,重寫字節(jié)碼文件,重寫方法進(jìn)行增強(qiáng),final類不能使用cglib
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容