Java 数组是 class 个实例吗?

Are Java arrays class instances?

Java 语言规范 says:

An object is a class instance or an array.

它也 says:

arrays [...] may be assigned to variables of type Object

但是the part that confuses me是:

The class Object is a superclass of all other classes

如果数组可以赋给对象类型的变量,那么它一定意味着数组可以是对象(不仅表现得像,而且 代替)。那么就是说一个数组是一个class实例,这好像和第一句不一致(如果是,那为什么要列为不同的东西呢?)。

这一切如何组合在一起?

The class Object is a superclass of all other classes

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

An object is a class instance or an array.

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

arrays [...] may be assigned to variables of type Object

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

Object[] obj = new Object[100];

obj instanceof Object 计算结果为真。

你的 second link 还说:

All methods of class Object may be invoked on an array.

所以从开发者的视角来看,至少,它是一个 Object,尽管没有 java.lang.Array(向我们公开)它是从中实例化的。

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

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

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

我看不出冲突。

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

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

您可以通过编译和 运行 以下 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

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

但是,Java 语言规范说 “对象是 class 实例或数组”是正确的,因为数组从根本上说是与常规对象不同。它们继承自 C++ 等语言,这些语言更深入地植根于计算机的低级体系结构。

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

All methods of class Object may be invoked on an array

这当然是对的,但在逻辑上并不意味着它们是对象。数组不是真正的对象;因此,它们不是真的 class 实例 ,因此句子 "The class Object is a superclass of all其他 classes 不适用于此处。

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

[这是我试图总结这里提出的要点。非常感谢大家的想法,欢迎大家补充!]