Object
。然而,数组具有像
length
这样的公共字段以及可以调用的方法,如.equals()
和.clone()
似乎(非常强烈地)暗示了相反的结论。原始数组的奇怪展示和行为的解释是什么?
需要注意的是,我刚才尝试在数组的
.clone()
方法上使用Eclipse的“打开实现”功能,希望能够查看该方法的定义方式和位置(因为它说明int[]从Object覆盖了它),但这实际上导致我的整个Eclipse崩溃了...Object
。length
这样的公共字段以及可以调用的方法,如.equals()
和.clone()
似乎(非常强烈地)暗示了相反的结论。.clone()
方法上使用Eclipse的“打开实现”功能,希望能够查看该方法的定义方式和位置(因为它说明int[]从Object覆盖了它),但这实际上导致我的整个Eclipse崩溃了...每种数组类型都有一个对应的类,所以int[]
有一个类,Foo[]
也有一个类。这些类由JVM创建。您可以通过int[].class
、Foo[].class
访问它们。这些类的直接父类是Object.class
public static void main(String[] args)
{
test(int[].class);
test(String[].class);
}
static void test(Class clazz)
{
System.out.println(clazz.getName());
System.out.println(clazz.getSuperclass());
for(Class face : clazz.getInterfaces())
System.out.println(face);
}
还有一个编译时的子类型规则,如果 A
是 B
的子类型,那么 A[]
是 B[]
的子类型。
请看下面的代码。它可以编译:
int[] arr = new int[2];
System.out.println(arr.toString());
根据JLS 第4.3节,Java 语言中有四种引用类型:类类型(§8)、接口类型(§9)、类型变量(§4.4)和数组类型(§10)。
而根据第10节的描述,在Java编程语言中,数组是对象(§4.3.1),动态创建的,并且可以被赋值给Object类型的变量(§4.3.2)。所有Object类的方法都可以在数组上调用。
因此,根据第一条引用,Array
其实不是一个类,而是另一种类型。但本质上,数组是对象,虽然不属于某个特定的Class
,而是属于Array
类型。所以它们并不是某个类的实例,而是定义为以这种方式创建的对象。
new int [2]()
……因为它不是真正的构造函数。为什么?API在哪里?解释是什么?它并不像你所说的那么简单。 - asterinew
...这是怎么工作的?原始数组基本上是一个对象和硬连线原始类型之间的交叉吗? - asteri[]
看作是类名的一部分。所以有原始类型 int
,有 Object
类型的 Integer
,还有另一种 Object
类型的 int[]
。 - Greg Giacovelli数组是一种容器对象,它可以保存固定数量的单一类型的值。
参见http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
Java中只有那几种基本类型,我们都知道。基本上,我们仍然需要几个步骤来创建一个数组,例如声明、构造或初始化(如果需要),这意味着数组确实是一个对象。
更深入地了解,原始类型可以使用原始值存储在内存中,但对象是一个地址(引用)。因此,我们可以想象一个悖论,如果数组是原始类型,我们如何将原始值存储在内存中?我认为与String相同,但String是一个final对象,因此您可以像基本类型一样轻松构造一个对象,例如String s =“s”。