メインコンテンツまでスキップ

オブジェクトと配列

オブジェクトも配列も,命令からは参照を通じて扱います。参照の保存には astore,読み出しには aload,返却には areturn を使います。

オブジェクトを作る

public static create()Ljava/lang/StringBuilder; {
new java/lang/StringBuilder
dup
ldc "prefix"
invokespecial java/lang/StringBuilder-><init>(Ljava/lang/String;)V
areturn
}

new の直後の参照は未初期化です。dup で同じ参照を残し,文字列を引数としてコンストラクタを呼びます。呼び出しが正常に終わると,残した参照を初期化済みの StringBuilder として使えます。

コンストラクタは値を返しません。new 自体がコンストラクタを実行するわけでもありません。

プリミティブ配列を作る

public static numbers()[I {
iconst_3
newarray I
dup
iconst_0
bipush 42
iastore
areturn
}

長さ 3 の int[] を作り,添字 0 に 42 を代入して返します。ほかの要素は初期値の 0 です。

iastore は下から配列参照,添字,値の三つを消費します。dup で配列参照を残しているため,代入後にその参照を返せます。

newarray の要素型には ZBCSIJFD を指定します。配列長は int として先に積みます。

参照型配列を作る

public static names()[Ljava/lang/String; {
iconst_2
anewarray Ljava/lang/String;
dup
iconst_0
ldc "first"
aastore
areturn
}

anewarray Ljava/lang/String;String[] を作ります。要素の初期値は null です。aastore で代入する参照は,実際の配列の要素型に代入可能でなければなりません。型が合わない場合は ArrayStoreException になります。

配列を読む

public static first([I)I {
aload_0
iconst_0
iaload
ireturn
}

iaload は配列参照と添字を取り出して,指定された int 要素を積みます。長さを調べるには arraylength を使います。

配列参照が null なら NullPointerException,添字が範囲外なら ArrayIndexOutOfBoundsException になります。生成時の長さが負なら NegativeArraySizeException です。

多次元配列

public static matrix()[[I {
iconst_2
iconst_3
multianewarray [[I 2
areturn
}

これは外側の長さが 2,内側の長さが 3 の int[][] を作ります。最後の 2 は確保する次元数です。次元数は 1 以上で,記述子に含まれる [ の数以下にします。たとえば multianewarray [[I 1 は外側だけを確保し,各要素は null のままです。

null と型検査

aconst_nullnull を積みます。checkcast は参照が指定した型として使えるかを検査し,成功時には同じ参照を残します。別のオブジェクトへの変換やコピーは行いません。null はこの検査に成功します。

instanceof は,指定した型のインスタンスなら 1,そうでなければ 0int として積みます。null の結果は 0 です。

フィールドの読み書きは クラス,フィールド,メソッド,初期化前の参照の制約は StackMapFrame と検証 に説明があります。