JAVA泛型的思考

看下边这段代码:

        Object[] arrays = new String[10];  //1
        arrays[0] = 1;  //2
        arrays[1] = "abc";  //3

编译是否会报错?运行是否会报错?

结果是编译不会报错,运行时第二行报错:java.lang.ArrayStoreException: java.lang.Integer

原因是:编译时根据静态类型(引用类型)做类型检查,arrays的引用类型是Object数组,所以第二行和第三行都能编译通过。运行时arrays的实际类型是String数组,第二行是在往String数组里添加Integer元素,所以抛出了异常。

再来看下一段代码:

        ArrayList<Object> list = new ArrayList<String>(); //1
        list.add(1);  //2
        list.add("123");  //3     

这段代码第一行编译的时候就会报错了。
泛型和数组不一样,持有String的泛型并不等价于持有Object的泛型,即使StringObject的子类型。
这里泛型和数组有很大的区别,因为虚拟机在运行期和编译器都能得到数组的具体类型信息,对数组中的元素做类型检查。而泛型在运行时已经被擦除了类型信息。无法在运行时做类型检查了。
如果允许上面的代码编译,编译后,就丢失了类型信息,即在运行时list中持有的是Object类型的对象,所以上诉代码中的第二行和第三行都能正常运行,那会导致ArrayList<String>存放了任意类型的元素(这段代码中存放了IntegerString)。这显然是不合理的。

因此,Java中,持有String的泛型不等价于持有Object的泛型,这是采用类型擦除带来的问题之一。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容