问题基本上是不言自明的。我无法找到数组的API(除了Arrays之外),但这只是定义了一堆用于处理实际数组的静态辅助函数。如果没有类,这似乎表明数组不能是Object
。
但是,数组包含length
等公共字段的事实以及可以像.equals()
和.clone()
一样调用的方法似乎(非常强烈地)建议完全相反。
对原始数组的奇怪表示和行为有什么解释?
作为一个说明,我试着在数组的.clone()
方法上使用“Open Implementation”Eclipse功能,希望我能够查看定义此方法的位置和方式(因为它说int []从Object覆盖它,但它实际上导致我的整个Eclipse冻结并崩溃......
答案 0 :(得分:58)
每个数组类型都有一个类,因此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[]
的子类型。
答案 1 :(得分:27)
Java Language Specification应该会给你一个想法:
数组类型的直接超类是Object。
每个数组类型都实现接口
Cloneable
和java.io.Serializable
。
对象是类实例或数组。
因此数组不是实例,因此您不需要构造函数来创建它们。而是使用Array Creation Expressions。
答案 2 :(得分:14)
请参阅以下代码。它编译: -
int[] arr = new int[2];
System.out.println(arr.toString());
现在,在任何基本类型上,您都无法调用Object类中定义的方法(toString()
)(或者,任何方法)。因此,数组本质上是Object
。
好的,你走了: -
来自JLS Section 4.3: -
有四种引用类型:类类型(§8),接口 类型(§9),类型变量(§4.4)和数组类型(§10)。
而且,Section 10: -
在Java编程语言中,数组是对象(§4.3.1),是 动态创建,可以分配给Object类型的变量 (§4.3.2)。可以在数组上调用Object类的所有方法。
所以,从第一个引用来看,Array
实际上并不是一个类..它是另一种类型..但是,基本上数组是对象,虽然不是某些Class
,但它们属于{ {1}}类型..所以它们不是某个类的实例,可能是Array
的对象被定义为以这种方式创建..
答案 3 :(得分:6)
如此简短,是的< Type> []是Object
的一种类型。它根据我的理解直接从Object
延伸。它上面有所有的Object方法,toString()
,hashCode()
,...加上一个名为length
的特殊公开变量。类java.util.Arrays
是用于处理数组类型的实用程序类。当您添加以下内容时,会有点混乱:int[]
不会从Object[]
继承。此外,与其他Object
类型不同,没有数组类型的构造函数。它们尊重new
关键字,但通常是为大小分配。这有点奇怪,但只是其中一种语言怪癖。
回答这个问题,是的,他们是一个对象。
答案 4 :(得分:3)
数组是一个容器对象,它包含固定数量的单个类型的值。
请参阅http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
答案 5 :(得分:0)
我们所知道的只有Java中的几种原始类型。基本上,我们仍然有几个步骤来创建一个数组,例如声明, 构造 或初始化(如果需要),这意味着数组确实是一个对象。
更深入地说,原始类型可以使用原始值存储在内存中,但对象是地址(引用)。所以我们可以想象一个悖论,如果数组是原始类型,我们如何将原始值存储在内存中?我认为和String一样,但String是一个最终对象,因此你可以用一种简单的方式构造一个对象,String s =“s”,就像一个原始类型。
答案 6 :(得分:-1)