【发布时间】:2019-05-23 08:01:53
【问题描述】:
数组没有“toList”函数,所以我们需要“Arrays.asList”辅助函数来进行转换。
这很奇怪:List 有自己的函数来转换为数组,但数组需要一些辅助函数来转换为 List。为什么不让数组有一个“toList”函数,这个Java设计背后的原因是什么?
非常感谢。
【问题讨论】:
标签: java arrays arraylist casting static
数组没有“toList”函数,所以我们需要“Arrays.asList”辅助函数来进行转换。
这很奇怪:List 有自己的函数来转换为数组,但数组需要一些辅助函数来转换为 List。为什么不让数组有一个“toList”函数,这个Java设计背后的原因是什么?
非常感谢。
【问题讨论】:
标签: java arrays arraylist casting static
因为 List 实例是一个实际的对象,而数组(出于 MOST 的意图和目的)是一个原语并且不公开方法。尽管从技术上讲,数组是一个对象,因此它们可以具有字段length 和诸如clone() 之类的方法调用,但是它们的类是在JVM 编译后创建的。
【讨论】:
要考虑的另一点是toArray() 在INTERFACE 上声明(特别是java.util.List 接口)。
因此,您必须在某个实现 List 的对象实例上调用 toArray()。
这可能有助于解释您问题的至少一部分:为什么它不是静态的......
正如其他人所指出的:Java 中的数组是一个相当“低级”的构造。尽管它是Object,但它并不是面向对象世界的真正组成部分。这适用于引用数组,例如String[],但更适用于原始数组,例如int[] 或float[]。这些数组是相当“原始的、连续的内存块”,在 Java 虚拟机中具有直接表示。
从语言设计的角度来看,Java 中的数组甚至可以被认为是对 C 和 C++ 的致敬。 有种语言是纯粹面向对象的,不存在纯数组或原始类型,但 Java 不是其中之一。
更具体地关注您的问题:
这里很重要的一点是Arrays#asList不进行任何转换。它只创建List,它是数组上的一个view。与此相反,Collection#toArray 方法确实创建了一个新数组。我在this answer about the lists that are created with Arrays#asList 中写了几句关于这种差异的含义。
此外,Arrays#asList 方法仅适用于元素为引用类型的数组(如String[])。它不适用于像long[] * 这样的原始 数组。但幸运的是,有几种方法可以解决这个问题,我在this answer about how to convert primitive arrays into List objects中提到了其中的一些。
* 事实上,Arrays#asList确实适用于像long[] 这样的原始数组,但它不会创建List<Long>,而是List<long[]>。这通常会造成混乱......
【讨论】:
从现代的角度来看,没有充分的理由说明数组缺少您提到的方法以及大量其他方法,这将使它们更易于使用。唯一客观的原因是“22 年前它对 Java 的设计者来说最有意义”。 1996 年是另一番景象,当时 C 和 C++ 是主要的通用编程语言。
您可以将其与例如Kotlin,一种编译成与 Java 完全相同的字节码的语言。它的数组是功能齐全的对象。
【讨论】:
数组是没有方法的原语(字符串除外),因此您必须使用另一个类的方法。列表是一种引用类型,因此它可以有方法。
【讨论】: