Cil*_*nco 4 java arrays bytecode
如果我使用像List,Vector或其他类似的普通类,我得到一个size()函数,它返回所考虑的类的长度,但如果我使用类的数组或默认数据类型,我得到一个公共成员长度,返回当前数组的长度.
int a[] = new int[3];
a.length; // used without ()
Vector<Integer> v = new Vector<Integer>();
v.length(); // used with ()
Run Code Online (Sandbox Code Playgroud)
这是为什么?我的意思是一个数组不是自己的类不是吗?因此,如果它不是类,它就不能有成员可变.我不知道如何在后台处理(ByteCode).我知道内存中的数组存储有指向数组第一个元素的指针,并且索引(i)内存指针被移位到ArrayPointer + i*(size of DataType).
现在您可以说计算机遍历数组的所有元素并计算所有元素,但计算机如何知道数组的结束位置以及下一个数组的起始位置?从哪里来的"成员可变"来自存储大小的数组?
我的意思是我们经常使用数组,但我知道在ByteCode中Java代码背后会发生什么.你能解释一下这是怎么回事吗?
Ant*_*ony 12
数组是Java中的对象,但它们与实际类不对应.实际上,JVM会动态地隐式创建数组类,但出于性能原因,它们不是实际的类.
由于它们是对象,因此它们可以存储在对象字段中并像往常一样传递.但是,它们在字节码级别上的处理方式略有不同.
首先,阵列与所创建的newarray,anewarray或multinewarray为分别单一维度灵长类动物的,单维对象,和多维数组的说明.相反,使用new指令创建常规对象.
使用*aload和*astore说明完成获取和设置元素.
此外,x.length不是真实的字段.相反,它被编译为arraylength指令.通过编译以下代码可以看出这一点.
public void test(int size){
int[] x = new int[size];
String[] y = new String[size];
System.out.println(x.length);
System.out.println(y.length);
}
Run Code Online (Sandbox Code Playgroud)
得到以下字节码
.method public test : (I)V
.limit stack 2
.limit locals 4
iload_1
newarray int
astore_2
iload_1
anewarray java/lang/String
astore_3
getstatic java/lang/System out Ljava/io/PrintStream;
aload_2
arraylength
invokevirtual java/io/PrintStream println (I)V
getstatic java/lang/System out Ljava/io/PrintStream;
aload_3
arraylength
invokevirtual java/io/PrintStream println (I)V
return
.end method
Run Code Online (Sandbox Code Playgroud)
尝试length通过手动创建字节码来访问该字段将导致异常,因为该字段实际上不存在.
.method static public main : ([Ljava/lang/String;)V
.limit stack 1
.limit locals 1
aload_0
getfield [Ljava/lang/String; length I
return
.end method
Run Code Online (Sandbox Code Playgroud)
结果是
Exception in thread "main" java.lang.VerifyError: Expecting reference to class i
n class ArrayTest at constant pool index 30 in method ArrayTest.main([Ljava/lang
/String;)V
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.getMethod0(Unknown Source)
at java.lang.Class.getMethod(Unknown Source)
at sun.launcher.LauncherHelper.getMainMethod(Unknown Source)
at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2978 次 |
| 最近记录: |