为什么 Java ArrayList 使用按元素转换而不是按数组转换? [英] Why does Java ArrayList use per-element casting instead of per-array casting?

查看:25
本文介绍了为什么 Java ArrayList 使用按元素转换而不是按数组转换?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java 的 ArrayList(可能还有许多其他类)内部发生的事情是有一个内部的 Object[] array = new Object[n];T 对象被写入其中.每当从中读取一个元素时,就会完成一个强制转换 return (T) array[i];.因此,每次阅读时都会进行转换.

What happens inside Java's ArrayList<T> (and probably many other classes) is that there is an internal Object[] array = new Object[n];, to which T Objects are written. Whenever an element is read from it, a cast return (T) array[i]; is done. So, a cast on every single read.

我想知道为什么要这样做.对我来说,似乎他们只是在做不必要的演员.只创建一个 T[] array = (T[]) new Object[n]; 然后只是 return array[i]; 不是更合乎逻辑,也稍微快一点吗? 没有演员表?这只是每个数组创建的一次强制转换,通常少于读取次数.

I wonder why this is done. To me, it seems like they're just doing unnecessary casts. Wouldn't it be more logical and also slightly faster to just create a T[] array = (T[]) new Object[n]; and then just return array[i]; without cast? This is only one cast per array creation, which is usually far less than the number of reads.

为什么他们的方法是首选?我不明白为什么我的想法不是严格意义上的更好?

Why is their method to be preferred? I fail to see why my idea isn't strictly better?

推荐答案

比那更复杂:泛型在字节码中被擦除,T[]的擦除是Object[].同样,get() 的返回值变成了 Object.为了保持类型系统的完整性,在实际使用类时插入一个检查转换,即

It's more complicated than that: generics are erased in byte code, and the erasure of T[] is Object[]. Likewise, the return value of get() becomes Object. To retain integrity of the type system, a checked cast is inserted when the class is actually used, i.e.

Integer i = list.get(0);

将被删除

Integer i = (Integer) list.get(0);

既然如此,ArrayList 中的任何类型检查都是多余的.但这真的无关紧要,因为 (T)(T[]) 都是 unchecked 强制转换,不会产生运行时开销.

That being the case, any type check within ArrayList is redundant. But it's really beside the point, because both (T) and (T[]) are unchecked casts, and incur no runtime overhead.

可以编写一个检查过的 ArrayList :

One could write a checked ArrayList that does:

T[] array = Array.newInstance(tClass, n);

这将防止堆污染,但以冗余类型检查为代价(您不能抑制调用代码中的合成转换).它还需要调用者为 ArrayList 提供元素类型的类对象,这会使它的 api 变得混乱,使其更难在通用代码中使用.

This would prevent heap pollution, but at the price of a redundant type check (you can not suppress the synthentic cast in calling code). It would also require the caller to provide the ArrayList with the class object of the element type, which clutters its api and makes it harder to use in generic code.

为什么禁止创建通用数组?

一个问题是检查数组,而未检查泛型.即:

One problem is that arrays are checked, while generics are unchecked. That is:

Object[] array = new String[1];
array[0] = 1; // throws ArrayStoreException

ArrayList list = new ArrayList<String>();
list.add(1); // causes heap pollution

因此,数组的组件类型很重要.我认为这就是 Java 语言的设计者要求我们明确使用哪种组件类型的原因.

Therefore, the component type of an array matters. I assume this is why the designers of the Java language require us to be explicit about which component type to use.

这篇关于为什么 Java ArrayList 使用按元素转换而不是按数组转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆