数组是原始类型还是对象(或其他完全不同的东西)?

时间:2012-10-09 19:07:51

标签: java arrays object primitive

问题基本上是不言自明的。我无法找到数组的API(除了Arrays之外),但这只是定义了一堆用于处理实际数组的静态辅助函数。如果没有类,这似乎表明数组不能是Object

但是,数组包含length等公共字段的事实以及可以像.equals().clone()一样调用的方法似乎(非常强烈地)建议完全相反。

对原始数组的奇怪表示和行为有什么解释?

作为一个说明,我试着在数组的.clone()方法上使用“Open Implementation”Eclipse功能,希望我能够查看定义此方法的位置和方式(因为它说int []从Object覆盖它,但它实际上导致我的整个Eclipse冻结并崩溃......

7 个答案:

答案 0 :(得分:58)

每个数组类型都有一个类,因此int[]有一个类,Foo[]有一个类。这些类由JVM创建。您可以int[].classFoo[].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);
}

还有一个编译时子类型规则,如果AB的子类型,A[]B[]的子类型。

答案 1 :(得分:27)

Java Language Specification应该会给你一个想法:

  

数组类型的直接超类是Object。

     

每个数组类型都实现接口Cloneablejava.io.Serializable

Moreover

  

对象是类实例或数组。

因此数组不是实例,因此您不需要构造函数来创建它们。而是使用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)