array、list多型與BaseMapper之謎
整理一些疑惑

Array

Java學著學著,有天用了一下go解題,才驚覺java中很少用Xxx[],都快忘記為什麼了

  • 數組、陣列,例如Cat[]
  • 長度固定,造的時候就要指定
  • 可以間隔存null
  • 不能泛型、但是協變 String[] is subtype of Object[]
    • 聽說是早期因為沒有泛型所以做的設計,沒人用了

List

List本身是接口,無法new List()

  • ArrayList是它的主要實現類
  • 另一個兄弟是LinkedList(鏈表,在高頻重複拔插有利)
  • 還有一個被遺忘的vector,特色是執行緒安全,但幾乎沒人用

ArrayList

  • 真正最常來當"數組"用的有序列表

  • 長度可變


多型

  • 目的是為了複用性與擴展性

    • 不需要每個子類都造相同的方法
  • 同一個行為具有多個不同表現形式或形態的能力

  • 三個必要條件:

    • 繼承或實現: 總之有上下關係

    • 重寫: 子類中重寫同名方法

    • 父類的引用指向子類: 子類賦給父類,例如List list = new ArrayList()

  • 動態綁定: 在編譯期虛擬調用,在執行期才確定調用的方法

    • 編譯看左,運行看右(子類)
  • 靜態多型: 成員屬性與靜態方法看父類的(左邊)

  • 結論: new誰就調用誰的方法,引用是誰,就用誰的成員和靜態

接口與類的關係

https://www.zhihu.com/question/19890792

  • Class (類)是一張圖紙——比如 F16 戰鬥機的設計藍圖
  • Interface (介面)是一種要求——比如“能發射導彈”
  • Instance (實例)是一個具體的東西——比如一架編號為 A123 的 F16

類可以實現介面,比如—— F16 的設計圖,是一張能夠發射導彈的飛機的設計圖

介面可以用來描述類,比如——這堆飛機設計圖都設計了“發射導彈”這個功能

所以,介面可以用來描述實例,比如—— F16 戰鬥機能發射導彈

現在假設你是個資深飛行員,但不是機械師。也就是說,你知道怎麼讓飛機發射導彈,雖然你不知道怎麼造出一架能發射導彈的飛機。那麼,如果你對機械師說,“給我一架能發射導彈的飛機”,你其實並不在乎他給你的究竟是 F15 還是 F16,也不關心這架飛機具體怎麼實現”發射導彈“這個功能,只要它能發射導彈就好。

Java8特性:

  • 接口中定義的靜態方法,只能透過接口去調用(類似工具類)
  • 預設方法:使用default修飾,實現類的物件,可以調用接口中的預設方法;若實現時重寫了方法,那調用的還是重寫的方法。只是說用default修飾,可以免去把抽象方法一一實現的過程而直接調用預設的方法

BaseMapper之謎

在MybatisPlus中,為何只要繼承了BaseMapper,就能@Autowired出那個接口的"實例"然後執行各種方法,往上查BaseMapper只是繼承了一個空的Mapper,他們都是接口沒看到實現類,這是什麼巫術?

public interface SysOssDao extends BaseMapper<SysOssEntity> {
.............
@Autowired
SysOssDao sysOssDao

Mapper介面的代理創建過程

詳解: https://juejin.cn/post/6844903793625137165

  • 掃描mapper介面基本包,將為註冊為BeanDefinition物件。
  • 設置BeanDefinition的物件的beanClass和sqlSessionFactory屬性。
  • 設置sqlSessionFactory屬性的時候,調用SqlSessionTemplate的構造方法,創建SqlSession介面的代理類。
  • 獲取BeanDefinition物件的時候,調用其工廠方法getObject,返回mapper介面的代理類。

最後我們在Service層,通過@Autowired UserMapper userDao注入屬性的時候,返回的就是代理類。執行userDao的方法的時候,實際調用的是代理類的invoke方法。 最後的最後,我們看一下這個代理類長什麼樣子。


上次修改於 2022-01-23