Java 是否无法从JVM';谁的观点?
我的疑问是: 在Java中,不允许从数组继承,即不能执行以下操作:Java 是否无法从JVM';谁的观点?,java,arrays,inheritance,jvm,jvm-hotspot,Java,Arrays,Inheritance,Jvm,Jvm Hotspot,我的疑问是: 在Java中,不允许从数组继承,即不能执行以下操作: class FloatVec extends float[] { // Vector methods. } FloatVec somevec = new FloatVec()[] { 1, 2, 3 }; // With array initializer. 或者更好: class FloatVec3 extends float[3] { // Regular accessor. public flo
class FloatVec extends float[]
{
// Vector methods.
}
FloatVec somevec = new FloatVec()[] { 1, 2, 3 }; // With array initializer.
或者更好:
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;
}
}
但是数组实际上实现了一个特定的接口,并且被认为是对象。也就是说,我们期望数组实例与对象公开的方法相同,再加上一个特定的数组字段,即最终的“长度”字段
所以我的问题是,即使Java语言不允许这种用法:
- 它可以在JVM中实现而不需要太多更改吗
- JVM是否将数组视为具有可继承类的任何对象
- JVM是否像对待枚举一样对待数组,即使数组对象自动从定义的数组类继承
- 数组类是否以可以从中继承的方式定义
int[]
实际上是int[].class
的一个实例,float[]
是float[].class
的一个实例。()您可以在自己的代码示例中看到这些类不能从中继承
JVM是否像对待枚举一样对待数组,即使数组对象自动从定义的数组类继承
是的,如果您有两个int[]
数组,比如a
和b
,那么a.getClass()==b.getClass()
数组类是否以可以从中继承的方式定义
正如您在自己的代码示例中所看到的,这些类不能从中继承。如前所述,它们没有源代码,是由JVM本身创建的
它可以在JVM中实现而不需要太多更改吗
这个问题不在堆栈溢出的范围之内,而且非常主观
它可以在JVM中实现而不需要太多更改吗
不,变化将是巨大的。它们会影响整个Java工具链,也会影响JLS/JVM抽象层或其下的大量第三方代码
没有任何东西可以阻止您下载(OpenJDK)源代码,并尝试自己进行实验。但在真正的Java中发生这种情况的可能性(依我看)非常小
我只在底部列出了一些技术问题。我相信还有其他人
JVM是否将数组视为具有可继承类的任何对象
没有
Java中的数组类型提供了少量方法。(根据对象API,方法有getClass
、hashCode
、toString
、clone
、wait
、notify
和notifyAll
。)
据我所知,这些方法的实际实现是由java.lang.Object
定义的本机方法提供的。但是由于JLS不允许您编写从数组继承的代码,所以JVM规范不需要提供实现此类代码的方法。实际上,事实并非如此
JVM是否像对待枚举一样对待数组,即使数组对象自动从定义的数组类继承
否。数组类型隐式继承自java.lang.Object
数组类是否以可以从中继承的方式定义
不存在这样的类别。数组类型隐式继承自对象
在JVM规范级别,使数组更“类化”有几个主要障碍:
- 数组类型的“类型字符串”表示形式(“[elem type”)只提到元素。实际的数组类型没有名称,如果有,则“Lname;”表示形式表示这是一个常规类,而不是数组类型
- 数组是由特殊的JVM指令创建的,这些指令将元素类型作为操作数而不是数组类型提供
除此之外,JVM实现还将假设阵列如何工作,以便高效地实现它们从理论上讲,使用invoke
指令调用数组上的非标准方法似乎是可能的,JVM解释器或JIT编译器将不知道如何利用它……即使您设法使invoke
通过类加载器和验证器
一旦解决了这个问题,那么就会出现这样一个问题:如果可以使用用户定义的超类声明数组,那么这些超类(大概)将能够拥有实例变量。但这意味着JVM规范需要更改,以便:
- 数组的堆节点可以保存实例变量以及数组本身
- 常规字段加载和存储指令适用于数组对象和递归对象
- 等等
如您所见,这个“小扩展”揭示了JVM中的许多其他设计决策。在Java中,最接近这一点的是Gil Tene的ObjectLayout项目——这离将其转化为Java还有很长的路要走,但这可能会使其成为Java 9的一部分这是一个很好的答案,但它更倾向于语言规范n、 这个问题专门问虚拟机。@Radiodef说得很好。我试图尽可能客观地回答这个问题,在阅读它时,我觉得“JVM做/可以做XYZ”这样的问题是无法回答的,因为JVM可以自由地以任何方式实现JLS中的任何功能。这进一步反映在提问者的假设中,即只有一个JVM实现。我认为这更适合于m