理系学生日記

おまえはいつまで学生気分なのか

コメント入れただけでクラスファイルは変化し得る

よくわかんないんだけど、コメント入れただけで Java のクラスファイルが変化するケースに遭遇したりしました。
例えば、こういう意味のないクラスを作ってコンパイルします。このとき生成されるクラスファイルの MD5 値を取っておきます。

public class Dummy {
	/**
	 * hoge fuga;
	 * @return
	 */
	public String hello() {
		return "hello world";
	}
}
% javac Dummy.java                                 
% md5 Dummy.class 
MD5 (Dummy.class) = 8d59e38037ad0152b4b502f69184ac38

次に、上記ソースファイルに対して、JavaDoc に対するコメントを追加します。これを再度コンパイルして MD5 を取ってみると、ハッシュ値が異なっている!!!!!

public class Dummy {
	/**
	 * hoge fuga;
	 * @return
	 * add!!!!
	 */
	public String hello() {
		return "hello world";
	}
}
% javac Dummy.java
% md5 Dummy.class 
MD5 (Dummy.class) = 7640c89b0ed590d0333a31a7507d9657

何が問題なのか

デグレードを防ぐために、ソース修正前後のクラスファイル同士を比較するというような必要が生じる場合があります。ぼくはこれを MD5 値の比較で実施していたのですが、本来はクラスファイルの差分としては出てきてほしくないコメント追加が、クラスファイルの差分という形で抽出されてしまった。

バイトコードは異なるのか

javap コマンドを用いると、クラスファイルからバイトコードを生成(ディスアセンブル)することができます。今回、MD5 値の異なる上記 2 つのクラスファイルをディスアセンブルし、その結果を比較してみましたが、2 つのバイトコードは全く同じでした。

% javap -c Dummy > old   # 最初のソースファイルをコンパイルしたクラスファイルに対して
% javap -c Dummy > new   # 二番目のソースファイルをコンパイルしたクラスファイルに対して
% diff -u old new
%

いったいこの状態でなんで MD5 値が変わるのか、よくわからないでいます。