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

huangapple go评论68阅读模式
英文:

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 已经开始解释和执行指令的阶段,还是在字节码验证期间出现的错误也被视为运行时错误?
英文:

I was reading about generics and type safety and found that arrays cannot be generic in java. I also understood the covariant nature of arrays which directed me to the array store exception. I understand why this exception occurs.

I tried the below code

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();
		
	}
}

This gives an ArrayStoreException as expected. My questions are

  1. My question is how does JVM check for array types at runtime?
    Does the compiler append any additional code or is there some predefined process that JVM follows before executing instructions?

  2. At what point this exception was raised?
    I thought that the ArrayStoreException would only occur if I try to read the array but I was wrong. So I am not understanding at what point exactly this error was raised.

Also, need a bit of clarification on the Java program execution process.

  1. Are run time errors and exceptions only the errors that occur while the program is in execution i.e JVM has started interpreting and executing the instructions or an error during bytecode verification is also considered run time error.

答案1

得分: 4

关于 JVM 如何在运行时检查数组类型的问题,当 JVM 解释字节码时,解释器会在解释 aastore 字节码指令时执行相关的运行时类型检查。相关的 JVM 规范链接是 https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.aastore

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

需要注意的是,只有当你修改字节码以尝试将引用分配到基本类型的数组时,这种情况才会引起验证器的注意。

关于什么时候引发此异常,当你将一个值分配到某种引用类型的数组中,并且你正在分配的值与数组的基本类型不具有“赋值兼容性”时,就会引发异常。

(需要注意的是,对于原始类型的数组,不会引发异常。如果你尝试将一个 long 赋值给一个 int[],或者将一个 boolean 赋值给一个 int[],将会得到编译错误。如果你尝试将一个 int 赋值给一个 long[],值将会被扩展。)

英文:

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

When the JVM is interpreting bytecodes, the interpreter performs the relevant runtime type checks when interpreting the aastore bytecode instruction. The relevant JVM spec link is https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.aastore.

The JIT compiler will translate the aastore instruction into native code that does the same thing, though it may optimize away any type checks that it can determine to be redundant.

Note this kind of thing would only come to the verifier's attention if you tweaked the bytecodes to attempt to assign a reference into an array of a primitive type.

> At what point this exception was raised?

When you assign a value into an array of some reference type and the value you are assigning is not assignment compatible with the base type of the array.

(Note that the exception won't be thrown for arrays of primitive types. If you try to assign a long into an int[] or a boolean into an int[] you will get a compilation error. If you try to assign an int into a long[] the value will be widened.)

huangapple
  • 本文由 发表于 2020年9月9日 15:09:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/63806449.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定