簡體   English   中英

Java類轉換規則

[英]Java Class Casting Rules

    public static void main(String[] args) {
       new Redwood().go();
    }
    void go() {
       go2(new Tree(), new Redwood());
       go2((Redwood) new Tree(), new Redwood());
    }
    void go2(Tree t1, Redwood r1) {
       Redwood r2 = (Redwood)t1;
       Tree t2 = (Tree)r1;
    }
}

給定Redwood擴展Tree類,則main()方法位於Redwood中,並且Tree是一個空類,僅具有默認構造函數; 該考試問題的答案是“當代碼嘗試將Tree轉換為Redwood時,將引發ClassCastException。”

我想知道為什么會引發異常以及在何處。 根據我的理解,您可以聲明Tree t1 = new Redwood(),為什么我不能直接將Tree投射到Redwood?

通過使用強制轉換,您實際上是在告訴編譯器“相信我。我是專業人士,我知道我在做什么,我知道盡管不能保證,但是我告訴你這個樹變量是肯定會成為紅杉。”

由於樹實際上不是一棵紅杉(它是一棵樹,您可以執行Tree tree = new Redwood();它將是一棵紅杉),因為您違反了這種信任,VM在運行時拋出異常(您告訴編譯器一切都會好起來的,不是!)

編譯器比盲目地接受所有內容要聰明一些,如果您嘗試將對象強制轉換為不同的繼承層次結構(例如,將紅木投射到String中),則編譯器會將其扔給您,因為它知道這種方法永遠無法工作。

因為您實際上只是在停止編譯器的抱怨,所以每次轉換時,都必須在if語句中使用instanceof(或有此作用的東西)來檢查是否不會導致ClassCastException。

請參考http://www.xyzws.com/Javafaq/why-down-casting-throws-classcastexception/125

每個Redwood都是一Tree 這就是為什么Tree t2 = (Tree) r1; 作品。

並非每Tree都是Redwood 這就是為什么Redwood r2 = (Redwood) t1; 如果t1Tree但不是Redwood將不起作用。

更正式地,請參見JLS§5.1.6

六種轉換稱為收窄參考轉換:

  • 從任何引用類型S到任何引用類型T,前提是S是T的適當超類型(第4.10節)。

  • 一個重要的特殊情況是,從類類型Object到任何其他引用類型的引用轉換范圍越來越窄(第4.12.4節)。

  • 從任何類類型C到任何非參數化接口類型K,只要C不是最終的並且不實現K。

  • 從任何接口類型J到非最終的任何非參數化類類型C。

  • 如果J不是K的子接口,則從任何接口類型J到任何非參數化接口類型K。

  • 從接口類型Cloneable和java.io.Serializable到任何數組類型T []。

  • 從任何數組類型SC []到任何數組類型TC [],條件是SC和TC是引用類型,並且從SC到TC的引用轉換范圍越來越窄。

此類轉換需要在運行時進行測試,以查明實際參考值是否為新類型的合法值。 如果不是,則拋出ClassCastException。

僅僅是因為每棵紅木都是一棵樹,但每棵樹都不是紅木。 編譯器足夠聰明,可以保護您的程序執行錯誤的操作。

類型的變量Tree不成立類型的對象Tree ; 相反,它持有null或對對象的引用 ,該對象保證可以用作Tree對象。 同樣,類型為Redwood的變量。

因為RedwoodTree繼承,所以保證Redwood對象可用作Tree對象,並且Tree類型的變量可能包含對該對象的引用。 如果嘗試將類型為Tree的變量轉換為Redwood類型的變量,則如果該變量持有null [因為Redwood類型的變量可以持有null ],或者該變量持有對該對象的引用,則此類轉換將成功可用作Redwood [因為該類型的變量可以保存任何此類引用],但如果該變量持有對不可用作Redwood的對象的引用,則將失敗[ Redwood類型的變量無法保存對此類對象的引用] 。

請注意,如果您嘗試強制轉換new表達式的結果,系統將表現為該結果已存儲到臨時變量中,並且強制轉換已應用於該臨時變量。 不管變量是否有任何實際方式可以保存對可用作Redwood的對象的引用,編譯器仍可能會表現出該變量可能或可能不包含此類引用的行為,並且只會發現它沒有代碼執行時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM