將一個類型強制轉(zhuǎn)換成另外一個類型的過程被稱為強制類型轉(zhuǎn)換。Java 程序設(shè)計語言提供了一種專門用于進行強制類型轉(zhuǎn)換的表示法疆液。
?double x = 3.405;
?int nx = (int) x;
將表達(dá)式 x 的值轉(zhuǎn)換成整數(shù)類型鲜漩,舍棄了小數(shù)部分暇务。
正像有時候需要將浮點數(shù)轉(zhuǎn)換成整數(shù)一樣科平,有時候也可能需要將某個類的對象引用轉(zhuǎn)換成另外一個類的對象引用铃辖。要完成對象引用的強制類型轉(zhuǎn)換,轉(zhuǎn)換語法與數(shù)值表達(dá)式的強制類型轉(zhuǎn)換類似窖梁,僅需要用一對圓括號將目標(biāo)類名括起來晃酒,并放置在需要轉(zhuǎn)換的對象引用之前就可以了。
public class Manager extends Employee {
...
}
Employee[] staff = new Employee[3];
staff[0] = new Manager("Carl Cracker", 75000, 1987, 12, 15);
staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15);
// 強制類型轉(zhuǎn)換
Manager boss = (Manager)staff[0];
進行強制類型轉(zhuǎn)換的唯一原因是: 要在暫時忽視對象的實際類型之后使用對象的全部功能窄绒。例如,由于某些元素是普通員工崔兴,所以 staff 數(shù)組必須是 Employee 對象的數(shù)組彰导。我們需要將數(shù)組中引用經(jīng)理的元素復(fù)原成 Manage 對象,以便能夠訪問新增加的所有變量敲茄。
在 Java中位谋,每個對象變量都有一個類型。類型描述了這個變量所引用的以及能夠引用的對象類型堰燎。例如掏父,staff[i] 引用了一個 Employee 對象(因此它還可以引用 Manager 對象)。
將一個值存入變量時秆剪,編譯器將檢查你是否承諾過多赊淑。如果將一個子類的引用賦給一個超類變量,編譯器是允許的仅讽。但將一個超類的引用賦給一個子類變量時陶缺,就承諾過多了。必須進行強制類型轉(zhuǎn)換洁灵,這樣才能夠通過運行時的檢査饱岸。
如果試圖在繼承鏈上進行向下的強制類型轉(zhuǎn)換,并且 “謊報” 對象包含的內(nèi)容,會發(fā)生什么情況呢苫费?
?Manager boss = (Manager) staff[1] ; // Error
運行這個程序時谅河,Java 運行時系統(tǒng)將注意到你的承諾不符,并產(chǎn)生一個 ClassCastException 異常莺掠。如果沒有捕獲這個異常料扰,那么程序就會終止。因此琅翻,應(yīng)該養(yǎng)成這樣一個良好的程序設(shè)計習(xí)慣:在進行類型轉(zhuǎn)換之前位仁,先查看是否能夠成功地轉(zhuǎn)換。為此只需要使用 instanceof 操作符就可以實現(xiàn)方椎。例如:
if(staff[1] instanceof Manager) {
boss = (Manager) staff[1];
...
}
最后聂抢,如果這個類型轉(zhuǎn)換不可能成功,編譯器就不會讓你完成這個轉(zhuǎn)換棠众。例如琳疏,下面這個強制類型轉(zhuǎn)換:
?String c = (String) staff[1];
將會產(chǎn)生編譯錯誤,這是因為 String 不是 Employee 的子類闸拿。
強制類型轉(zhuǎn)換注意事項:
- 只能在繼承層次內(nèi)進行強制類型轉(zhuǎn)換空盼。
- 在將超類強制轉(zhuǎn)換成子類之前,應(yīng)該使用 instanceof 進行檢查新荤。
如果 x 為 null揽趾,進行以下測試
?x instanceof C
不會產(chǎn)生異常,只是返回 false苛骨。之所以這樣處理是因為 null 沒有引用任何對象篱瞎,當(dāng)然也不會引用 C 類型的對象。
實際上痒芝,通過強制類型轉(zhuǎn)換來轉(zhuǎn)換對象的類型通常并不是一種好的做法俐筋。在我們的示例中,大多數(shù)情況并不需要將 Employee 對象強制轉(zhuǎn)換成 Manager 對象严衬,兩個類的對象都能夠正確地調(diào)用 getSalary 方法澄者,這是因為實現(xiàn)多態(tài)性的動態(tài)綁定機制能夠自動地找到正確的方法。
只有在使用 Manager 中特有的方法時才需要進行類型轉(zhuǎn)換请琳。如果出于某種原因發(fā)現(xiàn)需要在 Employee 對象上調(diào)用 Manager 中特有的 setBonus 方法粱挡,那么就應(yīng)該自問超類的設(shè)計是否合理〉テ穑可能需要重新設(shè)計超類抱怔,并添加 setBonus 方法,這才是更合適的選擇嘀倒。請記住屈留,只要沒有捕獲 ClassCastException 異常局冰,程序就會終止執(zhí)行。 一般情況下灌危,最好盡量少用強制類型轉(zhuǎn)換和 instanceof 運算符康二。