簡體   English   中英

投射到不相關的接口時為什么要編譯?

[英]Why does it compile when casting to an unrelated interface?

interface Printable {}
class BlackInk {}

public class Main {
    public static void main(String args[]) {
        Printable printable = null;
        BlackInk blackInk = new BlackInk();
        printable = (Printable)blackInk;
    }
}

如果前面的代碼已編譯並運行,則結果為ClassCastException,其位置為printable = (Printable)blackInk; 但是,如果將Printable更改為一個類,則因為blackInk無法轉換為Printable而無法編譯。 當Printable是接口時,為什么要編譯?

編譯器不知道這是行不通的:您可能擁有實現Printable的BlackInk子類。 那演員就好了。

在編譯器知道它不起作用的情況下,您會得到一個錯誤。

例如,如果將BlackInk final (這樣就不能有子類),則會出現錯誤。

根據Java語言規范部分:5.5.1 參考類型轉換

對於編譯時引用類型S (源)和編譯類型引用類型T (目標); 在將S轉換為T如果Sclass Type

  • 如果T是一個Class類型

    1. 然后要么T是的子類型S S是的子類型T 否則,將發生編譯時錯誤。
    2. 如果存在T的超類型XS的超類型Y ,從而XY都是可證明是截然不同的參數化類型,並且XY的擦除相同,則會發生編譯時錯誤

       class S{} class T extends S{} //// S s = new S(); T t = (T)s; // run time ClassCastException will happen but no compile time error 
  • 如果TInterface類型

    1. 如果S不是final類,那么,如果存在T的超類型XS的超類型Y ,使得XY都是可證明是截然不同的參數化類型,並且XY的刪除相同,發生編譯時錯誤 否則,強制轉換在編譯時始終合法( 因為即使S不實現TS的子類也可能
    2. 如果S是最終類,則S必須實現T,否則會發生編譯時錯誤。

這就是您的情況,即使在編譯時檢測到類強制轉換,在runtime也檢測到接口強制轉換。

類型轉換在run time發生(記住運行時多態性)。 編譯時,編譯器未發現代碼和編譯有任何問題,並且在運行時,它嘗試將類型blackinkprintable blackink鍵入,並且由於blackink未實現printable ,因此無法這樣做,從而導致錯誤。

暫無
暫無

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

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