1

使用时javax.mail.Message#setRecipeints,我第一次注意到一个东西,想进一步了解它。

这是我的代码:

List<InternetAddress> ccRecipients = new ArrayList<InternetAddress>();
// have a valid and working 
// method that fills the list with the data (InternetAddress objects)
message.setRecipients(
         RecipientType.CC, ccRecipients.toArray(new InternetAddress[0]));

在这里,我不明白为什么我们需要创建一个新InternetAddress数组并在toArray方法中的第 0 个索引处传递元素?

谁能解释为什么我们需要这样做?

我认为这与这种特殊的toArray方法有关。

我从 API 文档中阅读了以下内容,但没有得到最后一部分(粗体):

与 toArray() 方法一样,此方法充当基于数组的 API 和基于集合的 API 之间的桥梁。此外,此方法允许对输出数组的运行时类型进行精确控制,并且在某些情况下可用于节省分配成本

它如何节省分配成本?

4

4 回答 4

2

toArray()没有参数返回类型,ObjecttoArray(T[] a)返回类型T[]。这是 List 的通用方法。

于 2013-02-12T13:17:35.337 回答
0

这是您正在使用的方法的来源:ArrayList.toArray()

public <T> T[] toArray(T[] a) {
  if (a.length < size)
    // Make a new array of a's runtime type, but my contents:
    return (T[]) Arrays.copyOf(elementData, size, a.getClass());
  System.arraycopy(elementData, 0, a, 0, size);
  if (a.length > size)
    a[size] = null;
  return a;
}

首先,您没有传入对索引 0 的引用,而是一个长度为 0 的新数组。假设您的列表不为空,则新的零长度数组将太小而无法容纳它,而新的数组创建了正确的类型:Arrays.copyOf(elementData, size, a.getClass());

你可以传入一个足够大的数组来保存整个列表,然后将列表复制到你提供的数组中:System.arraycopy(elementData, 0, a, 0, size);至于这是否会节省你的分配成本,很难说。System.arraycopy()是本机方法,即平台相关。在没有看到它使用的代码的情况下,您只需要依赖一个事实,即本机实现通常应该更高效,并相信 JVM 编写者知道他们在做什么。

于 2013-02-12T13:19:00.630 回答
0

该方法的参数是一个数组,如果它足够大,则可以接收 Collection 的内容。我认为这种情况是,如果您已经分配了一个足够大以容纳集合的数组,则可以使用相同的数组而不是分配一个新数组。

请注意,您的代码正在传递一个长度为 0 的数组——只有当集合为空时才会返回该数组。如果 List 中有任何项目,将分配并返回一个新数组。

于 2013-02-12T13:19:09.070 回答
0

要使用它来节省分配成本,数组参数必须至少与 List 一样长。在这种情况下,数据被复制到参数引用的数组中。假设 List 总是相同的大小,你总是希望它是相同的元素类型,并且一次只需要一个数组。您可以重用相同的数组,而不是每次调用 toArray 时都创建一个新数组。

在实践中,更通常的做法是每次都创建一个新数组,但如果使用 List 大小而不是 0,则 toArray 将能够使用它。

于 2013-02-12T13:22:25.627 回答