場景:
當兩個重載函數的參數如下
void func(Map<Integer, String> map) {}
void func(Map<Integer, List<String>> map) {}
IDE會報出編譯錯誤:both methods have same erasure
解答:
由於Java泛型在編譯時擦除類型之后,上述方法會變成
void func(Map map)
查詢了一下,又有幾個相關概念需要了解和掌握。
https://www.jianshu.com/p/f9da328c91be
Java的泛型不同於C++的模板:Java泛型是"type erasure",C++模板是"reified generic"。
- type erasure:泛型類型僅存在於編譯期間,編譯后的字節碼和運行時不包含泛型信息,所有的泛型類型映射到同一份字節碼。
- reified generic:泛型類型存在於編譯和運行期間,編譯器自動為每一種泛型類型生成類型代碼並編譯進二進制碼中。
type erasure的本質
泛型(T) --> 編譯器(type erasure) --> 原始類型(T被Object替換)
泛型(? extends XXX) --> 編譯器(type erasure) --> 原始類型(T被XXX替換)
原始類型指被編譯器擦除了泛型信息后,類型變量在字節碼中的具體類型。
泛型(? extends XXX) --> 編譯器(type erasure) --> 原始類型(T被XXX替換)
原始類型指被編譯器擦除了泛型信息后,類型變量在字節碼中的具體類型。
type erasure導致泛型的局限性
類型擦除降低了泛型的泛化性,使得某些重要的上下文環境中不能使用泛型類型,具有一定的局限性。運行時隱含類型轉換的開銷: 使用泛型時,Java編譯器自動幫我們生成了類型轉換的代碼,這相對於C++模板來說無疑帶來了額外的性能開銷。
重載方法簽名沖突
一個類不能實現同一個泛型接口的兩種變體
https://blog.csdn.net/abc_12366/article/details/79177328
https://blog.csdn.net/weixin_34121282/article/details/88535522 Map泛型