王垠:一道 Java 面試題

描述
在這裏插入圖片描述

理解
題目中的這段程序在編譯器正常,運行時異常。錯誤出現在 b[1] = Integer.valueOf(42); 這一行代碼, a 賦值給 bab 指向同一對象 new String[2],而 String[] 的實現是不支持 set integer 操作。

這行引發運行時異常。從實現角度來說,Java的數組是協變的:也就說Java的類型系統認爲子類數組可以被賦值給父類數組。而這種賦值和對象的多態類似,它並不會實際改變數組元素的實際類型,於是乎在上述的例子中儘管b表面上是Object[]類型,但是運行時它的實際類型是String[],內部元素也只能添加字符串(因爲Java的數組不同與泛型,數組是存在運行時類型檢查的),於是就引發了這種現象:編譯期編譯通過(因爲表面的類型檢查認爲沒有什麼問題),運行時拋出異常(把事實上的Integer對象存進了String數組)。
作者:陸萌萌
鏈接:https://www.zhihu.com/question/371957442/answer/1017620831
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

如果想要編譯時報錯,我們可以用 List 代替 Array

public class TestJava {
    public static void f() {
        String[] a = new String[2];
        Object[] b = a;
        a[0] = "hi";
        b[1] = Integer.valueOf(42);  // 此處運行時異常
        System.out.println(a);
        System.out.println(b);
    }

    public static void o() {
        List<String> a = new ArrayList<>(2);
        List<Object> b = a;  // 此處類型檢查時會報錯
        a.set(0, "hi");
        b.set(1, Integer.valueOf(42));
    }

    public static void main(String[] args) {
        f();
    }
}

參考:
一道 Java 面試題:https://www.yinwang.org/blog-cn/2020/02/13/java-type-system
知乎討論:https://www.zhihu.com/question/371957442

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章