読者です 読者をやめる 読者になる 読者になる

Java Class ファイルを読む(1)

java

CSNagoya コンパイラの部 - アウトスタンディングなプログラマを目指してがきっかけ。

参考にしているもの

下ごしらえ

動作するけどシンプルなJavaプログラム

public class Base {
    public static void main(String args[]) {
    }
}

コンパイルする。

% javac -version
javac 1.6.0_10
% java -version
java version "1.6.0_10"
Java(TM) SE Runtime Environment (build 1.6.0_10-b33)
Java HotSpot(TM) Client VM (build 11.0-b15, mixed mode, sharing)
% javac Base.java 
% java Base
%

java Baseは何も出力せず終わる。


次にclassファイルを読みやすくする。

% hexdump -C Base.class > Base_dump.txt
% cat Base_dump.txt 
00000000  ca fe ba be 00 00 00 32  00 0f 0a 00 03 00 0c 07  |.......2........|
00000010  00 0d 07 00 0e 01 00 06  3c 69 6e 69 74 3e 01 00  |........<init>..|
00000020  03 28 29 56 01 00 04 43  6f 64 65 01 00 0f 4c 69  |.()V...Code...Li|
00000030  6e 65 4e 75 6d 62 65 72  54 61 62 6c 65 01 00 04  |neNumberTable...|
00000040  6d 61 69 6e 01 00 16 28  5b 4c 6a 61 76 61 2f 6c  |main...([Ljava/l|
00000050  61 6e 67 2f 53 74 72 69  6e 67 3b 29 56 01 00 0a  |ang/String;)V...|
00000060  53 6f 75 72 63 65 46 69  6c 65 01 00 09 42 61 73  |SourceFile...Bas|
00000070  65 2e 6a 61 76 61 0c 00  04 00 05 01 00 04 42 61  |e.java........Ba|
00000080  73 65 01 00 10 6a 61 76  61 2f 6c 61 6e 67 2f 4f  |se...java/lang/O|
00000090  62 6a 65 63 74 00 21 00  02 00 03 00 00 00 00 00  |bject.!.........|
000000a0  02 00 01 00 04 00 05 00  01 00 06 00 00 00 1d 00  |................|
000000b0  01 00 01 00 00 00 05 2a  b7 00 01 b1 00 00 00 01  |.......*........|
000000c0  00 07 00 00 00 06 00 01  00 00 00 01 00 09 00 08  |................|
000000d0  00 09 00 01 00 06 00 00  00 19 00 00 00 01 00 00  |................|
000000e0  00 01 b1 00 00 00 01 00  07 00 00 00 06 00 01 00  |................|
000000f0  00 00 03 00 01 00 0a 00  00 00 02 00 0b           |.............|
000000fd
%

Java Classファイルの構造

ClassFile {
    u4 magic;
    u2 minor_version;
    u2 major_version;
    u2 constant_pool_count;
    cp_info constant_pool[constant_pool_count-1];
    u2 access_flags;
    u2 this_class;
    u2 super_class;
    u2 interfaces_count;
    u2 interfaces[interfaces_count];
    u2 fields_count;
    field_info fields[fields_count];
    u2 methods_count;
    method_info methods[methods_count];
    u2 attributes_count;
    attribute_info attributes[attributes_count];
}

こうなっている。これが一つのclassファイルの形式。上から順番に読んでいく。

magic

u4 magic;
00000000  ca fe ba be 00 00 00 32  00 0f 0a 00 03 00 0c 07  |.......2........|

0xcafebabeというマジックナンバー。そのまんま。

minor_version, major_version

u2 minor_version;
u2 major_version;
00000000  ca fe ba be 00 00 00 32  00 0f 0a 00 03 00 0c 07  |.......2........|

マイナーバージョンとメジャーバージョン。これで Java 2 もしくは Java 2.0 を表す。


続きは2008-12-09