王垠:一道 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值