[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[jfriends-ml 10312] Re: Joshua Bloch さん と歓談会の様子
(株)ネットジーンの村山です.
> Gafterさんから出題された Another Quiz の写真ですが、
> ぼやけて判別不可能でした。解説をお願いできますか? > 村山さん
問題が次の通り.
----------
class Main{
public static void main( String [] args ){
int [][] a = null;
a[3][2] = 7;
}
}
をコンパイルすると,どんなバイトコードが生成されるか.
----------
解答は,次のようになります.
#これはJDKさえあれば,javap -cで誰にでも作れます.
----------
aconst_null
astore_0
aload_0
iconst_3
aaload
iconst_2
bipush 7
iastore
return
----------
このコードはコンパイルはされるものの,実行時に"aaload"の
時点でNullPointerExceptionが発生するはずです.
#ちなみにbipushのみ2バイト命令で,あとは全て1バイト命令の
#はず.伊達に「バイトコード」と呼ばれてるわけじゃないんですね.
簡単な解説を加えると
----------
aconst_null // オペランドスタックにnull参照をプッシュ
astore_0 // ローカル変数0にストア("a"に代入)
aload_0 // ローカル変数0をロードし,オペランドスタックにプッシュ
iconst_3 // 一次元目のインデックスとして定数3をプッシュ
aaload // 配列より2次元目の配列インスタンスへの参照をロード
// 実行時はこの時点でNullPointerExceptionとなるはず.
iconst_2 // 2次元目のインデックスとして定数2をプッシュ
bipush 7 // 代入する数値7をオペランドスタックへプッシュ.
// iconstは-1(m1)〜5までなので,6以上だと通常は
// bipushを使うことになる.
iastore // int配列にストア.
return // メソッドを終了
----------
短いわりには様々なバイトコードを使用する,良く出来た問題
だと思います.特にひねりもないので,おちついて考えれば正解
を出すのは難しくないはずです.
#それだけに,間違ったのは少しくやしい.多次元配列ということで
#最初にmultianewarrayのことで頭が一杯になったのは失敗だった.
#今までがJava2ME中心だったんで多次元配列はほとんど使わなかった
#ことも一因ではあるが,いずれにせよ間違いには違いない.
この程度の簡単な問題でも,
・ローカル変数名はバイトコードには影響を与えない.
・引数はバイトコードには直接は表れない.(影響はある.)
・staticメソッドにはthisがないので,ローカル変数0から使用可能.
・aconstはnullのみ.
・iconstは-1から5まで
・null参照チェック,配列の境界チェックは実行時に行われる
・多次元配列を直接アクセスする命令はない.(newはある.)
などといった,基本的な知識が試されます.
次回のJavaOneで「バイトコード パズラー」があれば,私も参加して
優勝を目指すんですけどねえ.最大の障害は参加者を集めることって
のが,ちょっと.....
あと,javacは普通は上のようなコードを出力するわけですが,
多分次のようなコードでも,無駄な部分が多いもののJavaVM仕様
には準拠している,正しいコードになると思います.
----------
aconst_null
dup
astore_1
bipush 3
aaload
sipush 7
bipush 2
swap
iastore
return
----------