理解List.java的`<T> T[] toArray(T[] a)`方法

3

有一个Java列表 List<int[]> lst = new ArrayList<>();

我有以下代码片段,我正在努力解读它们。所有这些都与理解泛型和方法 toArray() 有关

  1. lst.toArray(new int[0][]); - 这里的大小0并不重要。试图理解为什么?我也尝试查看 ArrayListtoArray 方法的实现。

  2. lst.toArray(new int[lst.size()][]) - 类似于(1),我可以使用 lst.size() 来初始化。这是否意味着(1)和(2)之间没有概念上的区别?

  3. 给定(1)和(2)都能正常工作,我尝试了 lst.toArray(new int[][]) - 这无法编译,并显示 Array initializer expected。这与Java的语法相关吗?在实例化数组时,大小是否是必须的,因此出现错误?

有人可以帮助我理解吗?


我从不使用这个,原因是它没有意义。这几乎是一种欺骗方法。你只是向编译器提供了对象类型。因此,首先,数组大小并不重要,其次,语法必须符合规范。 - Reilas
我从来不使用这个,因为有一个特定的原因,_它没有意义_。这几乎是一种技巧。你只是向编译器提供了对象类型。所以,_1_,数组大小无关紧要,而且_3_,语法必须符合规范。 - Reilas
我从来不使用这个,因为有一个特定的原因,_它没有意义_。这几乎是一个技巧。你只是向编译器提供对象类型。所以,_1_,数组大小无关紧要,而且_3_,语法必须符合要求。 - undefined
3个回答

3
lst.toArray(new int [0] [])- 这里的大小为0并不重要。想知道为什么?我也尝试过查看ArrayList中toArray方法的实现。
根据文档:
如果集合适合指定的数组中,则返回该数组。否则,将为指定数组分配一个新数组,其运行时类型与此集合相同且大小相同。
任何小于lst.size()的大小都会导致分配一个新数组。 lst.toArray(new int [lst.size()] [])- 和(1)类似,我可以使用lst.size()进行初始化。这是否意味着(1)和(2)之间没有概念上的区别?
几乎一样。唯一的区别是,在这里传入的数组对象将被使用,而不是分配一个新的数组。
给定(1)和(2)都能正确工作,我尝试了lst.toArray(new int [] [])- 这个编译不通过,并显示需要数组初始值设定项。这与Java的语法有关,如果你要实例化一个数组,大小是必须的,因此会出错。
这是正确的。

1
根据`toArray(T[] a)`的javadoc:
如果列表适合指定的数组,则返回该数组。否则,将分配一个新的数组,其运行时类型为指定数组的类型,并且大小与此列表相同。
因此,传递的数组的大小会影响是否分配新的数组。因此,在实践中,您可以传递零大小的数组(在您的情况下是`new int[0][]`),或者大小大于等于`lst.size()`的数组。传递正大小但小于列表大小的数组没有意义,因为它将被抛弃以创建适合列表的新数组。通常,程序员更喜欢传递零大小的数组,因为它简单而且短小。
关于第3点 - 您是完全正确的,Java要求在创建数组时定义数组的大小。

0
从技术上讲,你应该使用List而不是int[]。 尽管在Java中,int数组被认为是一个对象。因此,将其作为类型提供也是可以的。
集合框架是为对象而设计的,而不是原始数据类型。
"......这里大小为0并不重要。试图理解为什么?......"
基本上,编译器需要知道对象是什么,所以new int[0]就足够了。
"......这是否意味着(1)和(2)之间没有概念上的区别......"
多多少少是的。
"......我尝试过lst.toArray(new int[][])..."
"......这是否与Java的语法有关,即如果你实例化一个数组,大小必须是强制性的,因此会出错?"
确切地说,语法必须符合规范。
我推荐以下这本书,它很好地涵盖了这个主题——集合框架、对象和数组的互操作性。
Java: The Complete Reference, 第12版

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接