Arrays are objects in Java, but they don't correspond to real classes. Effectively, the JVM implicitly creates array classes on the fly, but for performance reasons, they aren't actual classes.
Since they are objects, they can be stored in Object fields and passed around like normal. However, they are treated a bit differently at the bytecode level.
First off, arrays are created with the newarray
, anewarray
, or multinewarray
instructions for single dimension primative, single dimension object, and multidimensional arrays respectively. By contrast, regular objects are created with the new
instruction.
Getting and setting elements is done with the *aload
and *astore
instructions.
Also, x.length is not a real field. Instead it gets compiled to the arraylength
instruction. This can be seen by compiling the following code.
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);
}
results in the following bytecode
.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
Attempting to access the length
field by manually creating bytecode will result in an exception, because the field doesn't actually exist.
.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
results in
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)