framework - list<> java




為什麼Java允許你轉換為集合? (2)

編譯器不會阻止代碼將類型轉換為接口,除非它可以確定關係是不可能的。

如果目標類型是接口,那麼它是有意義的,因為擴展 Foo 的類可以實現 Map<String, String> 。 但請注意,這僅適用於 Foo 不是 final 。 如果您使用 final class Foo 聲明了您的類,則該轉換將不起作用。

如果目標類型是一個類,那麼在這種情況下它只會失敗(嘗試 (HashMap<String, String>) this ),因為編譯器肯定知道 FooHashMap 之間的關係是不可能的。

作為參考,這些規則在 JLS-5.5.1 中描述(T =目標類型 - Map<String, String> ,S = source type - Foo

如果T [目標類型]是接口類型:

  • 如果S不是最終類(第8.1.1節),那麼,如果存在T的超類型X和S的超類型Y,那麼X和Y都可以證明是不同的參數化類型,並且X的擦除和Y相同,發生編譯時錯誤。
    否則,強制轉換在編譯時總是合法的(因為即使S沒有實現T,S的子類也可能)。

  • 如果S是最終類(第8.1.1節),那麼S必須實現T,否則會發生編譯時錯誤。

請注意引用文本中的 粗體斜體 註釋。

這個問題在這裡已有答案:

我有一個簡單的 foo 類,我可以轉換為集合接口( MapList ),沒有任何編譯器錯誤。 請注意, Foo 類不實現任何接口或擴展任何其他類。

public class Foo {

    public List<String> getCollectionCast() {
        return (List<String>) this;    // No compiler error
    }

    public Map<String, String> getCollection2Cast() {
        return (Map<String, String>) this;    // No compiler error
    }

    public Other getCast() {
        return (Other)this;     // Incompatible types. Cannot cast Foo to Other
    }

    public  static class Other {
        // Just for casting demo
    }

}

當我嘗試將 FooFoo 轉換為集合時,為什麼Java編譯器不會返回 不兼容的類型錯誤

Foo 沒有實現 Collection 。 我期望一個不兼容的類型錯誤,因為給定當前的 Foo 類簽名,這不能是一個 Collection


這不是因為它們是集合類,而是因為它們是 接口 Foo 沒有實現它們,但它的子類可以。 因此,這不是編譯時錯誤,因為這些方法可能對子類有效。 在 運行時 ,如果 this 不是實現這些接口的類,那麼它自然就是運行時錯誤。

如果將 List<String> 更改為 ArrayList<String> ,您也會得到編譯器時間錯誤,因為 Foo 子類可以實現 List ,但不能擴展 ArrayList (因為 Foo 沒有)。 類似地,如果你使 Foo final ,編譯器會給你的接口強制轉換錯誤,因為它知道它們永遠不會是真的(因為 Foo 不能有子類,並且不實現這些接口)。







casting