为什么数组是对象,但不能用作基类?

Hei*_*erg 66 java arrays inheritance compilation

Java语言规范指定了

在Java编程语言中,数组是对象(§4.3.1),是动态创建的,可以分配给Object类型的变量(§4.3.2).Object可以在数组上调用类的所有方法.

因此,考虑到数组是对象 - 例如,为什么Java设计者决定不允许继承和覆盖它,toString()或者equals()

当前语法不允许创建以数组作为基类的匿名类,但我不认为是他们决定的原因.

Den*_*ret 35

Java是非对象语言和非常慢的语言之间的折衷,当时一切都是对象(想想Smalltalk).

即使在最近的语言中,在阵列(通常是地图)的语言级别上具有快速结构也被认为是战略目标.大多数人不喜欢数组的可继承对象的权重,当然在JVM像JIT一样推进之前没有人想要这个.

这就是为什么数组虽然是对象,但并未设计为类实例("对象是类实例或数组").会有什么好处在其覆盖的方法的阵列上的能力,肯定不是一个很够一个制衡需要检查正确的方法申请(在我看来不是很大,一个足以抗衡代码读取的难度增加,类似于覆盖运算符时发生的情况).


Mar*_*oun 16

我遇到了HOVER THE HOOD - 对象和数组,解释了几乎所有关于JVM如何处理数组的知识.在JVM中,数组使用特殊的字节码处理,而不像我们熟悉的其他对象.

在JVM指令集中,除了数组之外,所有对象都使用相同的操作码集进行实例化和访问.在Java中,数组是完整的对象,并且与Java程序中的任何其他对象一样,是动态创建的.可以在调用Object类型的引用的任何地方使用数组引用,并且可以在数组上调用Object的任何方法.然而,在Java虚拟机中,使用特殊字节码处理数组.

与任何其他对象一样,数组不能声明为局部变量 ; 只有数组引用才可以.数组对象本身始终包含基本类型数组或对象引用数组.如果声明一个对象数组,则会得到一个对象引用数组.必须使用new显式创建对象本身并将其分配给数组的元素.

数组是动态创建的对象,它们用作容纳(常量)相同类型对象的容器.它看起来像数组不像任何其他对象,这就是为什么它们被区别对待的原因.

  • 数组不包含对象.它们包含原始值或对象*引用*.甚至`int [] []`也不是数组数组; 它是数组*引用*的数组.如果`foo`是一个数组数组(用C语言支持这类事情)语句`foo [0] [0] ++;`不会影响`foo [1] [0]`,但是这样Java的数组引用数组无法保证这一点.如果`foo [0]`和`foo [1]`都识别`int []`的相同实例,则`foo [0] [0] ++`将递增`foo [1] [0]`. (3认同)

Jux*_*hin 8

我想指出这篇文章.似乎数组和对象遵循不同的操作码.我不能诚实地总结它,但是看起来,数组根本Objects不像我们通常习惯的那样对待,因此它们不会继承Object方法.

对该帖子的作者给予全部学分,因为这是一篇非常有趣的阅读,既简短又详细.


通过多个来源进一步深入研究这个话题后,我决定给出我之前答案的更详细的版本.

首先要注意的是,对象数组的实例化在JVM中是非常不同的,它们遵循各自的字节码.

宾语:

Object实例化遵循一个简单的操作码new,它是两个操作数的组合 - indexbyte1&indexbyte2.一旦实例化,JVM就会将对该对象的引用推送到stack.所有对象都会发生这种情况,而与其类型无关.


阵列:

Array然而,操作码(关于阵列的实例化)被分成三个不同的代码.

newarray - 弹出长度,分配由atype指示的新类型的基本类型,推送新数组的objectref

newarray在创建涉及原始数据类型(byte short char int long float double boolean)而不是对象引用的数组时使用操作码.

anewarray - 弹出长度,分配由indexbyte1和indexbyte2指示的类的新对象数组,推送新数组的objectref

anewarray 在创建对象引用数组时使用操作码

multianewarray - 弹出维度数量的数组长度,分配由indexbyte1和indexbyte2指示的新的多维数组,推送新数组的objectref

multianewarray 在分配多维数组时使用指令


对象可以是类实例或数组.

Oracle Docs获取

类实例由类实例创建表达式显式创建

数组由数组创建表达式显式创建

这与有关操作码的信息密切相关.数组不是简单地开发为类接口,而是由数组创建表达式显式创建,因此自然不会隐式地能够继承和/或覆盖Object.

正如我们所看到的,它与数组可能包含原始数据类型的事实无关.在考虑了一些问题之后,遇到人们可能想要toString()或者equals()仍然是一个非常有趣的问题尝试和回答的情况并不常见.


资源:

Oracle-Docs第4.3.1章

Oracle-Docs第15.10.1章

Artima - UnderTheHood