Java 数组是类实例吗?

问题描述

Java 语言规范says

一个对象是一个类实例一个数组。

还有says

数组 [...] 可以分配给 Object 类型的变量

但是 the part that confuses me 是:

Object 类是所有其他类的超类

如果数组可以分配给对象类型的变量,那么它必须意味着数组可以是对象(不仅行为,而是成为)。那么就说明一个数组是一个类实例,这似乎和第一个引用不一致(如果是,那为什么会被列为不同的东西?)。

如何将所有这些组合在一起?

解决方法

没有矛盾。 数组也是对象,尽管是一种特殊的对象。
就像在说:鸟也是动物,虽然是一种特殊的动物。

您可以通过编译和运行以下 Java 代码来说服自己。

    String[] arrayOfStrings = { "bla","blah" };
    
    // examine the class hierarchy of the array 
    System.out.println("arrayOfStrings is of type "
            + arrayOfStrings.getClass().getSimpleName()
            + " which extends from "
            + arrayOfStrings.getClass().getSuperclass().getSimpleName());
    
    // assingning the array to a variable of type Object
    Object object = arrayOfStrings;

输出将是

arrayOfStrings is of type String[] which extends from Object
,

数组是 Java 本身提供给您的特殊类。它们都继承自通用超类 Object。由于它们继承自 Object,它们当然可以在需要 Object 的任何地方使用。数组的实例确实是这些类的实例。甚至可以像引用其他类的文字一样引用数组类:

    Class<int[]> intArrayClass = int[].class;

我认为没有冲突。

这很有用https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.8

,

Object 类是所有其他类的超类

Java 中的所有类都扩展了对象。类名实际上是 Object(专有名称大写)。这就是为什么所有类都有 toString() 和 hashCode() 方法的原因,因为它们都继承自 Object.class

一个对象是一个类实例或一个数组。

一个对象(小写,不是专有名称)是由 new 关键字生成的实例。即: File 是一个类,当您调用 new File() 时,您只是创建了一个 File 对象。老实说,我认为他们应该将其称为类实例。 (澄清:我希望他们永远不会将实例称为对象)

数组 [...] 可以分配给 Object 类型的变量

Object[] 是一个可以包含 Object 类型实例的数组。

Object[] obj = new Object[100];

obj instanceof Object 的计算结果为 true。

,

您的 second link 还说:

Object 类的所有方法都可以在数组上调用。

因此,至少从开发人员的 POV 来看,它是一个 Object,尽管它没有实例化的 java.lang.Array(暴露给我们)。

第二个迹象是数组也存储在堆上。

,

是的……也不是。确实,new Object[100] instanceof Objecttrue 确实如此,但这缺少 Java 中数组的真正性质。数组是对象(小写),但不是对象(大写)。例如,作为对象,您必须使用 new 运算符为它们分配空间。

然而,Java 语言规范说“一个对象是一个类实例或一个数组”是正确的,因为数组从根本上不同于常规对象。它们继承自 C++ 等语言,这些语言更深地植根于计算机的低级架构。

“数组 [...] 可以分配给 Object 类型的变量” 只是因为 Java 为我们程序员提供了一个接口,将数组称为对象.事实上,JLS says

Object 类的所有方法都可以在数组上调用

这当然是对的,但在逻辑上并不意味着它们是对象。数组不是真正的对象;因此,它们不是真正的类实例,因此句子“类对象是所有其他类的超类”在这里不适用。

总而言之,Java 不是纯粹的面向对象的编程语言(例如,原语不是对象,但它们仍然存在于 Java 中)。而数组是Java包含的一种语言特性,行为就像 Object类的类实例,但实际上不是它的类实例.

[这是我试图总结这里提出的要点。非常感谢你们所有人的想法,并随时添加更多!]