当泛型遇到重载
當泛型遇到了重載,好戲,就發生了。
請看下面代碼:
問題:代碼能正確編譯嗎?
這個題目是一個考察泛型的題目。java里面,泛型實際上是“偽泛型”,并不像C#那樣是實際上的泛型。
IDE會提示我們下面的錯誤:
Method test(List) has the same erasure test(List) as another method in type TR
在java中,泛型只存在于源代碼之中,在編譯過后的代碼中,泛型信息已經被“擦除”了。上面的代碼被編譯之后的樣子應該是下面類似的代碼:
兩個函數具有相同的簽名,當然編譯器會拒絕為我們編譯這樣的代碼。
在java這種偽泛型中,List和List,**編譯之后,**是相同的類型。
但是在c#這種真實泛型中,上面兩個就是不同的類型了。
故事到這里就結束了嗎??顯然沒有
------------------------------------昏昏咯咯-------------------------------------
看下面代碼:
問,這段代碼能正常編譯嗎?
熟悉class文件結構的人能知道,這段代碼能正常編譯(重載成功了!)。而且還能正常執行呢!!!
代碼輸出:
integer string疑問來了。jvm規定,函數的返回值并不參與“函數簽名”的生成,那么僅僅改變了函數返回值,從而讓不能編譯的代碼通過了編譯并且能正常執行了,這不是很矛盾嗎?
原因在于,雖然函數的返回值不參與函數簽名的生成,但是在class文件中,只要描述符不完全一致的兩個方法就能共存于一個class文件中。
【java代碼中,函數的特征簽名僅僅包括方法名稱、參數類型以及參數順序。但在字節碼中,特征簽名還包括了方法的返回值以及受查異常表,這就是為什么在class文件中,其他都相同僅僅返回值不同的兩個方法能共存的原因】
總結
- 上一篇: 系统架构师笔记(1)
- 下一篇: 系统架构师笔记(2)