慕田峪7331174
2019-07-30 11:02:24
從超類到子類的顯式轉換public class Animal {
public void eat() {}}public class Dog extends Animal {
public void eat() {}
public void main(String[] args) {
Animal animal = new Animal();
Dog dog = (Dog) animal;
}}賦值Dog dog = (Dog) animal;不會生成編譯錯誤,但在運行時會生成一個ClassCastException。為什么編譯器無法檢測到此錯誤?
3 回答

DIEA
TA貢獻1820條經驗 獲得超3個贊
通過使用演員你基本上告訴編譯器“相信我。我是一個專業人士,我知道我在做什么,我知道雖然你不能保證,我告訴你這個animal
變量肯定是要成為一只狗?!?/p>
由于動物實際上不是一只狗(它是一種動物,你可以這么做Animal animal = new Dog();
,它可能是一只狗)VM在運行時拋出異常,因為你違反了那種信任(你告訴編譯器一切都會好的,而且它是不?。?/p>
如果你嘗試在不同的繼承層次結構中強制轉換對象(例如將一個Dog轉換為一個String),那么編譯器會比盲目地接受所有內容更聰明一點,然后編譯器會將它拋回給你,因為它知道它永遠不會起作用。
因為你基本上只是停止編譯器的抱怨,所以每次你強制轉換它都很重要,以確保你不會在if語句中ClassCastException
使用by instanceof
(或者那種效果)。

皈依舞
TA貢獻1851條經驗 獲得超3個贊
因為理論上Animal animal
可以是一只狗:
Animal animal = new Dog();
一般來說,向下轉型不是一個好主意。你應該避免它。如果您使用它,最好包括一個支票:
if (animal instanceof Dog) { Dog dog = (Dog) animal;}

米脂
TA貢獻1836條經驗 獲得超3個贊
為了避免這種ClassCastException,如果你有:
class Aclass B extends A
你可以在B中定義一個帶有A對象的構造函數。這樣我們可以做“強制轉換”,例如:
public B(A a) { super(a.arg1, a.arg2); //arg1 and arg2 must be, at least, protected in class A // If B class has more attributes, then you would initilize them here}
添加回答
舉報
0/150
提交
取消