从JVM的角度来看,是否继承了原始数组?

The*_*ack 7 java arrays inheritance jvm jvm-hotspot

我的疑问是这个:

在Java中,不允许从数组继承,即,不能执行以下操作:

class FloatVec extends float[]
{
    // Vector methods.
}

FloatVec somevec = new FloatVec()[] { 1, 2, 3 }; // With array initializer.
Run Code Online (Sandbox Code Playgroud)

甚至更好:

class FloatVec3 extends float[3]
{
    // Regular accessor.
    public float getX() {
        return this[0];
    }
    // Or say, make it the 'this' implicit like with other fields:
    public void setVec(float x, float y, float z) {
        [0] = x;
        [1] = y;
        [2] = z;
    }
    // And specific vec3 methods like:
    public float dotProduct() {
        float x = this[0];
        float y = this[1];
        float z = this[2];
        return x * x + y * y + z * z;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是数组实际上实现了一个特定的接口并被视为对象.也就是说,人们期望数组实例与Object公开的方法相同,加上特定的数组字段,即最终的"长度"字段.

所以我的问题是,即使Java语言不允许这种用法:

  • 它可以在没有太多更改的情况下在JVM中实现吗?

  • JVM是否将数组视为具有可继承的类的任何对象?

  • JVM是否将数组视为枚举,即使数组对象从定义的数组类中自动继承?

  • 数组类是以某种方式定义的,它可以从中继承吗?

Ste*_*n C 9

它可以在没有太多更改的情况下在JVM中实现吗?

不,这些变化将是巨大的.它们会影响整个Java工具链,也会影响JLS/JVM抽象层或其下的大量第三方代码.

没有什么可以阻止您下载(OpenJDK)源代码并尝试自己做这个实验.但实际 Java中发生这种情况的可能性很小(IMO).

我在最底层列出了一些技术问题.我确信还有其他人.

JVM是否将数组视为具有可继承的类的任何对象?

没有.

Java中的数组类型提供了少量方法.(的方法是getClass,hashCode,toString,clone,wait,notifynotifyAll...作为每ObjectAPI.)

据我所知,这些方法的实际实现是由定义的本机方法提供的java.lang.Object.但是由于JLS不允许您编写从数组继承的代码,因此JVM规范不需要提供实现此类代码的方法.而且,在实践中,它没有.

JVM是否将数组视为枚举,即使数组对象从定义的数组类中自动继承?

不可以java.lang.Object.数组类型隐式继承自.

数组类是以某种方式定义的,它可以从中继承吗?

没有这样的类.数组类型隐式继承自Object.


在JVM规范级别,使阵列更像"类似"有几个主要障碍:

  • 数组类型("[elem-type")的"类型字符串"表示仅提及该元素.实际的数组类型没有名称,如果是,那么"Lname;" 表示被,这是一个普通的类,而不是数组类型.

  • 数组由特殊的JVM指令创建,这些指令将元素类型提供为操作数而不是数组类型.

除此之外,JVM实现将假设数组如何工作以便有效地实现它们.即使(根据JLS)理论上似乎可以使用invoke指令在数组上调用非标准方法,JVM解释器或JIT编译器也不知道该怎么做...即使你以某种方式设法偷偷invoke过去了类加载器和验证器.

一旦你越过那个,那么就存在这样的问题:如果数组可以用用户定义的超类声明,那么那些超类(可能)就能够拥有实例变量.但这意味着JVM规范需要改变,以便:

  • 数组的堆节点可以包含实例变量以及数组本身,

  • 常规字段加载和存储指令适用于数组对象以及reculare对象,

  • 等等.

正如您所看到的,这个"小扩展"在JVM中揭示了许多其他设计决策.


ast*_*eri 6

JVM是否将数组视为具有可继承的类的任何对象?

每个原始数组类型确实有一个类.例如,int[]实际上是实例,int[].class而a float[]是实例float[].class.(JLS 10.8)您可以在自己的代码示例中看到这些类无法继承.

JVM是否将数组视为枚举,即使数组对象从定义的数组类中自动继承?

是的,如果你有两个int[]数组,说ab,然后a.getClass() == b.getClass().

数组类是以某种方式定义的,它可以从中继承吗?

正如您在自己的代码示例中所看到的,这些类无法继承.它们没有源代码,并且是由JVM本身创建的,正如其他答案和代码示例所述.

它可以在没有太多更改的情况下在JVM中实现吗?

这个问题超出了Stack Overflow的范围,并且非常主观.