配列割り当てバイトコード解析

5103 ワード


int [][]a=new int[3][5];
System.out.println(a[0][0]);

0が印刷されます
別に
参照タイプの配列は値を割り当てずにnullが格納されます
基本データ型、例えばintが値を付けずに格納されているのは0である.
double floatはデフォルトで格納されていないのはすべて0です.
基本データ型配列はデータを格納、参照は参照を格納....

String[] x = {"o", "k","ok"};

ここに格納されているのはStringオブジェクトの参照です....
int[] x = {0}; int[]x=new int[1]と
バイトコードを見ると同じ効果がわかります...

// 0 0:iconst_1
// 1 1:newarray int[]
// 2 3:dup
// 3 4:iconst_0
// 4 5:iconst_0
// 5 6:iastore
// 6 7:astore_1
// 7 8:iconst_1
// 8 9:newarray int[]
// 9 11:astore_2
// 10 12:return

int[][] x = {{1},{1,2},{1,2,3},new int[1]};

バイトコードの表示

public static void main(String args[])
{
// 0 0:iconst_3
// 1 1:anewarray int[][]
// 2 4:dup
// 3 5:iconst_0
// 4 6:iconst_2
// 5 7:newarray int[]
// 6 9:dup
// 7 10:iconst_0
// 8 11:iconst_2
// 9 12:iastore
// 10 13:dup
// 11 14:iconst_1
// 12 15:iconst_3
// 13 16:iastore
// 14 17:aastore
// 15 18:dup
// 16 19:iconst_1
// 17 20:iconst_2
// 18 21:newarray int[]
// 19 23:dup
// 20 24:iconst_0
// 21 25:iconst_1
// 22 26:iastore
// 23 27:dup
// 24 28:iconst_1
// 25 29:iconst_5
// 26 30:iastore
// 27 31:aastore
// 28 32:dup
// 29 33:iconst_2
// 30 34:iconst_2
// 31 35:newarray int[]
// 32 37:dup
// 33 38:iconst_0
// 34 39:iconst_3
// 35 40:iastore
// 36 41:dup
// 37 42:iconst_1
// 38 43:iconst_4
// 39 44:iastore int
// 40 45:aastore ( )
// 41 46:astore_1
// 42 47:aload_1
// 43 48:invokestatic #3
// 44 51:getstatic #4
// 45 54:aload_1
// 46 55:iconst_0
// 47 56:aaload // 48 57:iconst_0
// 49 58:iaload
// 50 59:invokevirtual #5
// 51 62:return
}

//次元配列と多次元配列の作成は異なるコマンドであることにも注意
[color=red]int [][]a=new int[3][5];
なお、ここでは、x 2次元配列が15個のint要素ではなく3個のint配列オブジェクトを配置していることがバイトコードでわかる
一つはnewarrayが基本タイプ配列です
もう1つはanewarrayの参照タイプを入れる配列なので、この2つの配列はClassではありません.

public static void change(int ai[][])
{
// 0 0:aload_0 0
// 1 1:iconst_0 0
// 2 2:aaload a[0]
// 3 3:iconst_0 0
// 4 4:iconst_1 1
// 5 5:iastore a[0][0] int astore_1 !

// 6 6:return
}


対応方法

public static void main(String[] args) {
// TODO Auto-generated method stub

int a[][]={{2,3},{1,5},{3,4}};

change(a);
System.out.println(a[0][0]);
}
public static void change(int[][]a)
{
a[0][0]=1;
}
}

メソッドchange内のパラメータがStringBufferであればchange内でappendを行います
彼は変わるのか』?

public static void main(String[] args) {
// TODO Auto-generated method stub

StringBuffer buffA=new StringBuffer( "a ");
StringBuffer buffB=new StringBuffer( "b ");
change(buffA,buffB);
System.out.println(buffA+ ", "+buffB);

}
public static void change(StringBuffer x,StringBuffer y){
x.append(y);
y=x;


もう一度見る
彼のバイトコード

// 0 0:aload_0
// 1 1:aload_1
// 2 2:invokevirtual #15
// 3 5:pop StringBuffer .....
// 4 6:aload_0
// 5 7:astore_1
// 6 8:return