运行时间在java时间执行的过程是怎样的,JVM在运行时间是如何检查数组类型的?

What is the process of runtime execution in java and how does JVM checks for array types at run time?

我正在阅读有关泛型和类型安全的内容,发现数组在 java 中不能是泛型的。我还了解数组的协变性质,这将我引向了数组存储异常。我明白为什么会出现这个异常。

我尝试了下面的代码

class SuperClass {
    
}

class SubClass extends SuperClass {
    
}
public class ArrayCheck {
    
    public static void main (String args[]) {   
        SubClass arr[] = new SubClass[10];
        
        arr[0] = new SubClass();
        
        SuperClass[] arr1 = arr;
        arr1[1] = new SuperClass();
        
    }
}

这按预期给出了 ArrayStoreException。我的问题是

  1. 我的问题是 JVM 如何在 运行 时检查数组类型? 编译器是否附加了任何额外的代码,或者 JVM 在执行指令之前是否遵循了一些预定义的过程?

  2. 这个异常是在什么时候引发的? 我认为 ArrayStoreException 只有在我尝试读取数组时才会出现,但我错了。所以我不明白这个错误到底是在什么时候出现的。

此外,需要对 Java 程序执行过程进行一些说明。

  1. 运行 时间错误和异常仅是程序正在执行时发生的错误,即 JVM 已开始解释和执行指令或字节码验证期间的错误也被视为 运行 时间错误。

My question is how does JVM check for array types at runtime ?

JVM在解释字节码时,解释器在解释aastore字节码指令时会进行相关的运行时类型检查。相关的 JVM 规范 link 是 https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.aastore.

JIT 编译器会将 aastore 指令翻译成执行相同操作的本机代码,尽管它可能 优化掉 它可以确定的任何类型检查多余的。

请注意,如果您调整字节码以尝试将引用分配给原始类型的数组,这种事情只会引起验证者的注意。

At what point this exception was raised?

当您将一个值赋给某个​​引用类型的数组,而您赋值的值与数组的基类型赋值不兼容

(请注意,原始类型的数组不会抛出异常。如果您尝试将 long 分配给 int[] 或将 boolean 分配给 int[] 你会得到一个编译错误。如果你试图将一个 int 分配给一个 long[] 值将被扩大。)