Specification)』(以下、JVM仕様)には、JVMで利用可能なバイトコードの仕様が説明されています。JVM仕様では、バイトコードの命令列は、人間が読み取ることができるアルファベットの命令名(ニーモニック)と、その数値表現である1byteのオペコードで構成されています。クラスファイルはオペコードのみで構成されており、単なるバイナリデータです。試しにクラスファイルをテキストエディタで開いてみても、画像などのバイナリデータと同様に、文字にならないデータが表示されるだけです(クラスやフィールド、メソッドの名前は、バイトコード内にそのまま文字列として保存されているので、そこだけは何とか読み取ることができます)。実は、あまり知られていませんが、そのような目的のためのツールが、JavaのSDKにデフォルトで用意されているのです。そのツールは「javap」というコマンドで、このコマンドを利用すればクラスファイルを人間が読み取れる形式に変換することができます。javapコマンドは、引数にクラス名を渡して実行します。クラスファイルそのもの(つまり、「.class」拡張子が付いたファイルのパス)を渡すのではないことに注意してください。javapコマンドで指定できる主なオプションは、以下のとおりです。メソッド内のスタックサイズ、ローカル変数と引数の個数を出力する注:Javaにおける「メンバ」とは、そのクラス内で宣言されているフィールド、メソッド、内部クラス/インタフェースの総称です。コマンドの使用法は、以下のとおりです。<クラス名>それでは、簡単なサンプルクラスファイルを利用して試してみます。以下のソースコード「HelloWorld.java」をコンパイルして、生成されたクラスファイルを読むことにします。}}-cオプションを付けてjavapコマンドを実行すると、次のような結果が標準出力に表示されます(左端にある行番号は説明のために付加したもので、実際の出力には付いていません)。}この逆アセンブルされたクラスファイルについて、簡単に説明しておきます。3行目ではそのクラスファイルが作られた、元のソースコードのファイル名が表示されます。4行目は、そのクラスの宣言です。5〜9行目は、コンストラクタの命令列です。ソースコード「HelloWorld.java」にはコンストラクタはありませんでしたが、コンストラクタが省略された場合でも、バイトコードへコンパイルされるときにデフォルトのコンストラクタが挿入されるようになっています。#9)、voidを返してメソッドを終了しています(return)。11〜16行目が、ソースコードで宣言したmainメソッドの命令列になります。#29)、最後にvoidを返してメソッドを終了しています(return)。このように、javapコンパイラを利用すれば、コンパイルされたクラスファイルの命令列を読み取ることができます。勉強やデバッグに利用してみてください。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。