java泛型程序设计——翻译泛型表达式+翻译泛型方法
【0】README
0.1) 本文描述+源代碼均 轉自 core java volume 1, 旨在理解 java泛型程序設計 的 翻譯泛型表達式+翻譯泛型方法 的知識;
【1】翻譯泛型表達式
1.1)當程序調用泛型方法時, 如果擦除了泛型返回類型, 編譯器插入類型轉換;
- 1.1.1)看個荔枝:
- 擦除getFirst的返回類型后將返回Object類型。 編譯器自動插入 Employee 的強制類型轉換。
- 也就是說, 編譯器吧這個方法調用翻譯為兩條虛擬機指令(Commands):
- C1)對原始方法 Pair.getFirst 的調用;
- C2)將返回的Object類型 強制轉換為 Employee 類型;
1.2)當存取一個泛型域時也要插入強制類型轉換。
- 1.2.1)假設 Pair 類的first 域 和 second 域都是 公有的(這不是種好的編程風格, 但在java語法中,這是合法的)。
表達式: Employee buddy = buddies.first; 也會在結果字節碼中插入強制類型轉換;
【2】翻譯泛型方法
2.1)類型擦除也會出現在泛型方法中。
public static <T extends Comparable> T min(T[] a):是一個完整的方法族;- 2.1.1)擦除類型后, 只剩下一個方法:
- 注意, 類型參數T 已經被擦除了, 只留下了限定類型 Comparable;
2.2)方法擦除帶來了兩個復雜問題。
- 2.2.1)看個荔枝:
對以上代碼的分析(Analysis):
- A1)上述類的類型變量擦除后, 為
- A2)令人感到奇怪的是, 存在另一個從Pair 繼承的setSecond方法, 即
- Attention)此時要注意, DateInterval內部應該是重寫了 Pair的 setSecond方法, 結果擦除類型參數后, 就不是重寫了, 破壞了類的多態性;
A3)它們顯然不是同一種方法, 因為有不同的類型參數, 一個是Object , 而另一個是 Date;(這里是干貨)
A4)然而不應該不一樣, 考慮下面的語句序列:
- A5)這里, 希望對setSecond 的調用 具有多態性, 并調用最合適的那個方法。 由于pair 引用DateInterval 對象,所以應該調用 DateInterval.setSecond;
- A6)出現的問題:在于類型擦除與多態發生了沖突, 確實, 如上面的Attention所說, 變量類型擦除破壞了類的多態性;
- A7)解決方法: 就需要編譯器在 DateInterval 類中生成一個橋方法(bridge method):
2.3)上述引入了橋方法:要想了解他的工作過程, 跟蹤下列語句 pair.setSecond(aDate);
- 2.3.1)變量pair 已經說明為類型 Pair , 并且這個類型只有一個簡單的方法叫做 setSecond, 即 setSecond(Object);
- 2.3.2)虛擬機用 pair 引用的對象調用這個方法: 這個對象是 DateInterval 類型的, 因而將會調用 DateInterval.setSecond(Object) 方法;
- 2.3.3)這個方法是合成的橋方法: 它調用 DateInterval.setSecond(Date)方法,在正是我們想要的;
2.4)橋方法也可以變得很奇怪, 如 DateInterval 方法覆蓋了 getSecond()方法:
class DateInterval extends Pair<ate> {public Date getSecond() {return (Date) super.getSecond().clone();} }對以上代碼的分析(Analysis):
- A1)在擦除的過程中, 有兩個getSecond方法:
- A1.1) Date getSecond() // defined in DateInterval
- A1.2) Object getSecond() // overrides the method defined in Pair to call the first method
- A2)不能這樣編寫代碼(因為具有相同參數的兩個方法是不合法的, 他們都沒有參數)。
A3)但在虛擬機中, 用參數類型和返回類型確定一個方法, 因此, 編譯器可能產生兩個僅返回 類型不同的 方法字節碼, 虛擬機能夠正確處理這個情況;
Annotation)A1)橋方法不僅用于泛型類型; 還有, 在一個方法覆蓋另一個方法時可以指定一個更嚴格的返回類型:
對以上代碼的分析(Analysis):
- A1) Object.clone 和 Employee.clone 方法被說成具有協變的返回類型;(具有協變的返回類型)
- A2)實際上, Employee 類有兩個克隆方法(Methods):
- M1) Employee clone();// defined above
- M2) Object clone() ; // synthesized bridge method, overrides Object.clone;
- A3)合成的橋方法調用了新定義的方法;
Conclusion)總之, 需要記住有關java泛型轉換的事實:
- C1)虛擬機中沒有泛型, 只有普通的類和方法;
- C2)所有的類型參數都是用它們的限定類型替換;
- C3)橋方法被合成來保持多態;
- C4)為保持類型安全性, 必要時插入強制類型轉換;
總結
以上是生活随笔為你收集整理的java泛型程序设计——翻译泛型表达式+翻译泛型方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓电玩游戏(安卓电游戏)
- 下一篇: java泛型程序设计——调用遗留代码