前川/研究のための/Java Virtual Machine
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[前川/研究のための]]
#contents
*Java Virtual Machineとは? [#dcb5f0e4]
-クラスファイルを読み込んで実行するだけの機械。
*Java言語とJavaVMの対応 [#c678bb1f]
-1つのJava言語のクラスは1つのJavaVMのクラスファイルに対応している。
-1つのJava言語のオブジェクトは1つのJavaVMのオブジェクトに対応している。
-1つのJava言語のメソッドは1つのJavaVMのメソッドに対応している。
-1つのJava言語のコンストラクタはJavaVMのメソッドに対応している。
*クラスローダについて [#if35b2ca]
**システムクラスローダ [#uf6ed515]
-1つのJavaVMに1つだけ存在。
-CLASSPATHにて定義。
**ユーザクラスローダ [#fafcc0b6]
-1つのJavaVMに複数存在可能。
-Java.lang.ClassLoaderクラスのサブクラスのインスタンスとして実行可能。
*メモリ上の各エリア [#g8090567]
&ref(http://aslweb.u-aizu.ac.jp/~s1130205/Gallery/MemoryStructure.png);
**メソッドエリア [#d531c79c]
-クラスの置き場
**ヒープ [#u7d890e0]
-インスタンス置き場
**Javaスタック [#u8f20f94]
-スレッド毎に割り当てられる場。
**フレーム [#jf79b6af]
-メソッド呼び出し毎にJavaスタック上に積まれる作業場。
-実行終了時に破棄。
**ローカル変数 [#wb3ad910]
-メソッド上に作られるJava言語のローカル変数とメソッド引数置き場
-サイズはコンパイラにより指定。
-番号により管理されている。
-0番にはthisが入る。
**オペランドスタック [#ic9d2eb5]
-メソッド上に作られるオペランド置き場
-サイズは(ry
*クラスファイル [#i87db6de]
&ref(http://aslweb.u-aizu.ac.jp/~s1130205/Gallery/NestingClassfileStructure.png);
class ClassFile{
u4 magic; //CA FE BA BE
u2 minor_version; //minor version
u2 major_version; //major version
u2 constant_pool_count; // コンスタントプールエントリ配列の要素数
cp_info[] constant_pool = new cp_info[constant_pool_count - 1]; //コンスタントプールエントリ配列
u2 access_flags; //このクラスのアクセスフラグ
u2 this_class; //このクラスへのクラス参照のCPエントリ番号
u2 super_class; //スーパークラスへのクラス参照のCPエントリ番号
u2 interface_count; //実装/継承しているインタフェースのCPエントリ番号配列の要素数
u2[] interfaces = new u2[interfaces_count]; //実装/継承しているインタフェースのCPエントリ番号配列
u2[] fields_count; //フィールド配列の要素数
field_info[] fields = new field_info[fields_count]; //フィールド配列
u2 fields_count; //メソッド配列の要素数
field_info[] methods = new method_info[fields_count]; //メソッド配列
u2 attributes_count; //クラス属性の配列要素数
attribute_info[] attributes = new attribute_info[attributes_count]; //クラス属性の配列
}
**magic number(4 bytes) [#k6eaac9b]
-"''CA FE BA BE''" はJavaクラスファイルの識別子。
**minor_version(2 bytes) [#w1fb7362]
-クラスファイルを生成したコンパイラのバージョン番号。
**major_version(2 bytes) [#mbceae82]
-minor_versionと同じ。
**constant_pool_count(2 bytes) [#b2093914]
-コンスタントプールエントリ配列の要素数。
**constant_pool [#d7c00728]
&ref(http://aslweb.u-aizu.ac.jp/~s1130205/Gallery/InheritanceConstantPoolStructure.png);
-[constant_pool_count -1]個のcp_info構造体が存在する。
-タグバイトによりinfoの構造は変わる。
-infoの構造の詳細は下記を参照。
class cp_info{
u1 tag; //タグバイト
u1[] info; //エントリデータの中身
}
-タグ一覧
|Name|Value(0x)|Description|
|CONSTANT_Utf8|1|Utf8形式に変換されたユニコード文字列|
|CONSTANT_Integer|3|intリテラル|
|CONSTANT_Fload|4|floatリテラル|
|CONSTANT_Long|5|longリテラル|
|CONSTANT_Double|6|doubleリテラル|
|CONSTANT_Class|7|クラスまたはインタフェースへの参照|
|CONSTANT_String|8|Stringリテラル|
|CONSTANT_Feildref|9|フィールド参照|
|CONSTANT_Methodref|a|っクラスで宣言されたメソッドへの参照|
|CONSTANT_InterfaceMethodref|b|インタフェースで宣言されたメソッドへの参照|
|CONSTANT_NameAndType|c|メソッド参照やフィールド参照の名前と型の部分を定義するもの|
***cp_info [#jeee99bb]
-タグによるエントリデータ構造の違いを説明する。
-簡略化のためにcp_infoをスーパークラス、その他をサブクラスとした。
abstract class cp_info{
u1 tag;
}
***CONSTANT_Utf8_info [#t383d801]
-ユニコード文字列をUtf形式で格納するコンスタントプールエントリ。
class CONSTANT_Utf8_info extends cp_info{
u2 length; //バイト長
u1[] bytes = new u1[length]; //文字列データ
}
-CONSTANT_Utf8_infoに格納されるデータ一覧
|データの種類|説明|
|Stringリテラルの文字列データ|Stringリテラルの文字列データ。|
|クラスやインタフェースの完全修飾名|コンスタントプールエントリの所属するクラスファイルで定義されているクラスやインタフェースの完全修飾名。スーパークラスの完全修飾名。extendsまたはimplementsしているインタフェースの完全修飾名。|
|フィールド名|コンスタントプールエントリの所属するクラスファイルのクラスで宣言されたフィールドの名前。コンスタントプールエントリの所属するクラスファイルから参照されている別クラスのフィールドの名前。|
|フィールドディスクリプタ|コンスタントプールエントリの所属するクラスファイルのクラスで宣言されたフィールドのフィールドディスクリプタ。コンスタントプールエントリの所属するクラスファイルから参照されている別クラスのフィールドのフィールドディスクリプタ。|
|メソッド名|コンスタントプールエントリの所属するクラスファイルのクラスで宣言されたメソッドの名前。コンスタントプールエントリの所属するクラスファイルのクラスから参照されている別クラスのメソッドの名前。|
|メソッドディスクリプタ|コンスタントプールエントリの所属するクラスファイルのクラスで宣言されたメソッドのメソッドディスクリプタ。コンスタントプールエントリの所属するクラスファイルのクラスから参照されている別クラスのメソッドのメソッドディスクリプタ。|
|属性名|CodeやConstantValueなどの、属性の名前を表す文字列。|
***CONSTANT_Integer_info [#ud081851]
-int型リテラルを格納するコンスタントプールエントリ。
class CONSTANT_Integer_info extends cp_info{
u4 bytes;
}
***CONSTANT_Float_info [#afc75fe5]
-float型リテラルを格納するコンスタントプールエントリ。
class CONSTANT_Float_info extends cp_info{
u4 bytes;
}
***CONSTANT_Louble_info [#le3650da]
-long型リテラルを格納するコンスタントプールエントリ。
class CONSTANT_Long_info extends cp_info{
u4 high_bytes;
u4 low_bytes;
}
***CONSTANT_Double_info [#a59cc4cc]
-double型リテラルを格納するコンスタントプール。
class CONSTANT_Double_info extends cp_info{
u4 high_bytes;
u4 low_bytes;
}
***CONSTANT_Class_info [#v2f3ff7c]
-クラスまたはインタフェースへの参照を格納するコンスタントプールエントリ。
-配列のクラス(?)もここに当てはまる。
class CONSTANT_Class_info extends cp_info{
u2 name_index; //クラスまたはインタフェースの完全限定名を格納したCONSTANT_Utf8エントリのindex
}
***CONSTANT_String_info [#k07ff1f5]
-Stringリテラルへの参照を格納するコンスタントプールエントリ。
class CONSTANT_String_info extends cp_info{
u2 string_index; //リテラルの値である文字列データを格納したCONSTANT_Utf8エントリへのindex
}
***CONSTANT_Fieldref_info [#oa0678e7]
-フィールドへの参照を格納するコンスタントプールエントリ。
class CONSTANT_Fieldref_info extends cp_info{
u2 class_index; //フィールドの所属するクラスへの参照を格納するCONSTANT_Class_infoのindex
u2 name_and_type_index; //フィールドの単純名とフィールドディスクリプタをまとめたCONSTANT_NameAntType_infoのindex
}
***CONSTANT_Methodref_info [#n247af33]
-クラス(インタフェースではない)で宣言されたメソッドの参照を格納するコンスタントプールエントリ。
class CONSTANT_Methodref_info extends cp_info{
u2 class_index; //メソッドの所属するクラスへの参照を格納するCONSTANT_Class_infoのindex
u2 name_and_type_index; //メソッドの単純名とメソッドディスクリプタをまとめたCONSTANT_NameAndType_infoのindex
}
***CONSTANT_InterfaceMethodref_info [#fe217c4d]
-インタフェース(クラスではない)で宣言されたメソッドへの参照を格納するコンスタントプールエントリ
class CONSTANT_InterfaceMethodref_info extends cp_info{
u2 class_index; //メソッドの所属するインタフェースへの参照を格納するCONSTANT_Class_infoのindex
u2 name_and_type_index; //メソッドの単純名とメソッドディスクリプタをまとめたCONSTANT_NameAndType_infoのindex
***CONSTANT_NameAntType_info [#f465c08d]
-フィールドやメソッドの参照の名前と型をまとめたものを格納するコンスタントプールエントリ。
class CONSTANT_CONSTANT_NameAndType_info extends cp_info{
u2 name_index; //フィールドもしくはメソッドの単純名を格納したCONSTANT_Utf8エントリのindex
u2 descriptor_index; //ふぃ0るどもしくはメソッドのディスクリプタを格納したCONSTANT_Utf8エントリのindex
}
}
**access_flags(2 bytes) [#w9568c8e]
-このクラスのアクセス制限について示しています。
-コンパイラはクラスもインタフェースも共通の構造をもったクラスファイルとして取り扱う。違いはACC_INTERFACEビットが立っているかどうか。
|Name|Bits|Description|
|ACC_PUBLIC|0000 0000 0000 0001|このクラスまたはインタフェースはpublicである|
|ACC_FINAL|0000 0000 0001 0000|このクラスはfinalである。|
|ACC_SUPER|0000 0000 0010 0000|新しい方のinvokesptialのセマンティクスを使う。|
|ACC_INTERFACE|0000 0010 0000 0000|これはクラスではなくインタフェースである。|
|ACC_ABSTRACT|0000 0100 0000 0000|このクラスまたはインタフェースはabstractである。|
**this_class(2 bytes) [#o1d3f75e]
-このクラスへのクラス参照のエントリ番号
**super_class(2 bytes) [#rec0af7b]
-このクラスのスーパークラスへのクラス参照のエントリ番号
**interfaces_count(2 bytes) [#yb875503]
-interfaces配列の要素数。
**interfaces [#wc0d3022]
-interfaces_count個のCONSTANT_Classエントリ番号。
**fields_count [#d8a9e228]
-fields配列の要素数。
**fields [#ma10ae29]
-[fields_count -1]個のfield_info構造体が存在する。
-field_infoの構造の詳細は下記を参照。
***field_info [#m7f7ad1b]
class field_info{
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info[] attributes = new attribute_info[attributes_count];
}
-access_flags(2 bytes)
|Name|Bits|Description|
|ACC_PUBLIC|0000 0000 0000 0001|このフィールドはpublicである。|
|ACC_PRIVATE|0000 0000 0000 0010|このフィールドはprivateである。|
|ACC_PROTECTED|0000 0000 0000 0100|このフィールドはprotectedである。|
|ACC_STATIC|0000 0000 0000 1000|このフィールドはstaticである。|
|ACC_FINAL|0000 0000 0001 0000|このフィールドはfinalである。|
|ACC_VOLATILE|0000 0000 0100 0000|このフィールドはvolatileである。|
|ACC_TRANSIENT|0000 0000 1000 0000|こnフィールドはtransientである。|
-name_index(2 bytes)
--フィールドの単純名を格納するCONSTANT_Utf8エントリのindex
-descriptor_index(2 bytes)
--フィールドディスクリプタを格納するCONSTANT_Utf8エントリのindex
-attributes_counts
--このフィールド上の属性配列の要素数。
-attributes
--属性配列
--ConstantValueとSyntheticのみ。詳しくは下記参照。
***ConstantValue [#oe78aca9]
-staticフィールドの初期値が入る。
class ConstantValue_attribute extends attribute_info{
ConstantValue_attribute(){
attribute_length = 2;
}
u2 constantvalue_index; //フィールドの初期値(リテラル)へのエントリ番号。リテラルの型はフィールドの型により決まる。
}
-フィールドの型と初期値のコンスタントプールエントリ(リテラルの型)
|フィールドの型|初期値のコンスタントプールエントリ|
|int|CONSTANT_Integer|
|short|CONSTANT_Integer|
|char|CONSTANT_Integer|
|byte|CONSTANT_Integer|
|boolean|CONSTANT_Integer|
|long|CONSTANT_Long|
|float|CONSTANT_Float|
|double|CONSTANT_Double|
|String|CONSTANT_String|
**methods_count(2 bytes) [#h095b5ba]
-メソッド配列の要素数。
**methods [#jcb3a083]
-[methods_count -1]個のmethod_info構造体が存在する。
-method_infoの構造の詳細は下記を参照。
***method_info [#d3ac42bb]
class method_info{
u2 access_flags; //(2 bytes)
u2 name_index; //(2 bytes)メソッドの単純名を格納するCONSTANT_Utf8エントリのindex
u2 descriptor_index; //(2 bytes)メソッドディスクリプタを格納するCONSTANT_Utf8エントリのindex
u2 attributes_count; //(2 bytes)このメソッド上の属性配列の要素数
attribute_info[] attributes = new attribute_info[attributes_count]; //属性配列
}
-access_flags
|Name|Bits|Description|
|ACC_PUBLIC|0000 0000 0000 0001|このメソッドはpubicである。|
|ACC_PRIVATE|0000 0000 0000 0010|このメソッドはprivateである。|
|ACC_PROTECTED|0000 0000 0000 0100|このメソッドはprotectedである。|
|ACC_STATIC|0000 0000 0000 1000|このメソッドはstaticである。|
|ACC_FINAL|0000 0000 0001 0000|このメソッドはfinalである。|
|ACC_SYNCHRONIZED|0000 0000 0010 0000|このメソッドはsynchronizedである。|
|ACC_NATIVE|0000 0001 0000 0000|このメソッドはnativeである。|
|ACC_ABSTRACT|0000 0100 0000 0000|このメソッドはabstractである。|
***Exceptions_atrribute (メソッドのみで使われる属性その1) [#ad448cbb]
-throws節で宣言されている例外の情報を格納する属性。
class Exceptions_attribue extends attribute_info{
u2 number_of_exceptions; //例外配列の要素数
u2 exception_index_table = new u2[number_of_exceptions]; //例外配列。throws節で宣言した例外のクラスを表したCONSTANT_Classエントリのindex
}
***Code_attribute [#x3bab4f0]
-インストラクションコードそのものを格納する属性。
class Code_attribute extends attribute_info{
u2 max_stack; //オペランドスタックの上限値
u2 max_locals; //ローカル変数の上限値
u4 code_length; //インストラクションコード列のバイト長
u1[] code = new u1[code_length]; //インストラクションコード列
u2 exception_table_length; //例外ハンドラ配列の要素数
exception_info[] exception_table = new exception_info[exception_table_length]; //例外ハンドラ配列。このメソッドで定義されているすべてのcatchステートメントの情報を配列にして格納したもの。
u2 attributes_count; //属性配列の要素数
attribute_info[] attributes = new attribute_info[attribute_count]; //属性配列
class exception_info{ //例外ハンドラ
u2 start_pc; //ハンドラの有効範囲の始点
u2 end_pc; //ハンドラの有効範囲の終点
u2 handler_pc; //ハンドラが呼ばれたときにジャンプするアドレス
u2 catch_type; //ハンドラのcatchするクラスのCPエントリ番号
}
}
***LineNumbertable_attribute(メソッドのCode属性で使われる属性その1) [#g8bdd82b]
-ソースコードの行番号とインストラクションコード列の対応関係を格納している。
-主にデバックのために使われる。
class LineNumberTable_attribute extends attribute_info{
u2 line_number_table_length; //行番号配列の要素数。
line_number_info[] line_number_table = new line_number_info[line_number_table_length]; //行番号配列。
class line_number_info{ //行番号。
u2 start_pc; //行番号に対応するインストラクションコードの開始位置。
u2 line_number; //行番号。
}
}
***LocalVariableTable_attribute(メソッドのCode属性で使われる属性その2) [#d4153ae6]
-ソースコードのメソッドの中で使われているローカル変数に関する情報を格納している。
-主にデバックのために使われる。
class LocalVariableTable_attribute extends attribute_info{
u2 local_variable_table_length; //ローカル変数配列の要素数
local_variable_info[] local_variable_table = new local_variable_info[local_variable_table_length]; //ローカル変数配列
class local_variable_info{ //ローカル変数
u2 start_pc; //変数のスコープの開始
u2 length; //変数のスコープの終わりまでの長さ
u2 name_index; //変数名を格納するCONSTANT_Utf8エントリ番号
u2 descriptor_index; //変数の型のを格納するCONSTANT_Utf8エントリ番号
u2 index; //対応するJavaVMローカル変数の番号
}
}
***Synthetic_attribute(フィールドとメソッドの両方で使われる属性) [#gf391eac]
-Java言語レベルでインナークラスを使えるようにするために作られた属性。
class Synthetic_attribute extends attribute_info{
}
**attribute_info [#v395fb15]
class attribute_info{
u2 attribute_name_index; //属性名のCPエントリ番号
u4 attribute_length; //属性データのバイト長
u1[] info = new u1[attribute_length]; //属性データ配列。属性の種類により構造が異なる。
}
-下記のクラスをスーパークラスとし、他の属性関係クラスはサブクラスとなる。
abstract class attribute_info{
u2 attribute_name_index; //属性名のCPエントリ番号
u4 attribute_length; //属性データのバイト長
}
***SourceFile_attribute(クラスでのみ使われる属性 その1) [#lca9ecf5]
-ソースファイルに関する情報を格納する属性。
class SourceFile_attribute extends attribute_info{
SourceFile_attribute(){
attribute_length = 2;
}
u2 sourcefile_index; //ソースファイル名を格納したCONSTANT_Utf8エントリのindex
}
***InnerClasses_attribute(クラスでのみ使われる属性 その2) [#f07cbfb9]
-インナークラスに関する情報を格納する属性。
class InnerClasses_attribute extends attribute_info{
u2 classes_count; //インナークラス配列の要素数
inner_class_info[] classes = new inner_class_info[classes_count]; //インナークラス配列
class iner_class_info{ //インナークラス
u2 inner_class_index; //インナークラス参照を格納するCONSTANT_Classエントリのindex
u2 outer_class_index; //アウト-クラス参照を格納するCONSTANT_Classエントリのindex
u2 inner_class_acces_flags; //インナークラスのアクセスフラグビットの集まり。ClassFile構造体のaccess_flagsと共通。
}
}
*Technical term [#v03ff14e]
**ディスクリプタ [#ve4307dc]
-フィールドやメソッドの型を表す文字列。
***フィールドディスクリプタのBNF表記 [#la90806b]
<フィールドディスクリプタ> ::= <data_type>
<data_type> ::= <base_type> | <object_type> | <array_type>
<base_type> ::= B|C|D|F|I|J|S|Z
<object_type> ::= L<fullclassname>;
<array_type> ::= [<data_type>
-プリミティブ型ディスクリプタ
|ディスクリプタ|Java言語の型|
|B|byte|
|C|char|
|D|double|
|F|float|
|I|int|
|J|long|
|S|short|
|Z|boolean|
**メソッドディスクリプタのBNF表記 [#ocd1c010]
-()でくくった部分が引数の型を表す。
-()に続く文字列が返り値の型を表す。
<メソッド> ::= (<argument_types>) <return_type>
<argument_types> ::= <data_type>*
<return_type> ::= <data_type> | V
|ディスクリプタ|Java言語の型|
|V|void|
**クラスローダ [#g26f0b46]
***実行時のクラス合成 [#t03cea40]
-例
c = cl.loadClass("BBDash");
-上記の命令が実行されるとき下記の動作が起こる。
+BBDashクラスをロードしようとする。
+しかし、BBDashクラスのクラスファイルがメソッドエリアにないためClassLoaderクラスのfindLocalClass()が呼ばれる。
+findLocalClass()がBBDashクラスを上位クラスのクラスファイルからバイトコードで読み込み、それをコンソールからユーザ入力に基づいて書き換えてから、そのバイトコードをdefineClass()でメソッドエリアのクラスに展開する。
**コンスタントプールリゾリューション [#w570203d]
-例
new java/lang/StringBuffer
-バイトコードでは
BB xx xx
-とあらわされる。xx xxにはCONSTANT_Classのエントリ番号が入る。
-CONSTANT_ClassはCONSTANT_UTF8エントリ番号を保持しているだけ。
--参照するクラスがメソッドエリアのどのアドレスに格納されているのかという情報をもっていない。
-最初に上記の命令を実行するときにはjava/lang/StringBufferクラスのクラスファイルをメモリにロードし、xx xx番目のコンスタントプールエントリをロードしたクラスへのポインタで置き換える。
**リゾルブ [#u79ad7c8]
-シンボリック参照をポインタに書き換えること。
**コンストラクタ [#h6c9f224]
-オブジェクトを生成する際に必ず実行される初期化処理を記載した部分です。
終了行:
[[前川/研究のための]]
#contents
*Java Virtual Machineとは? [#dcb5f0e4]
-クラスファイルを読み込んで実行するだけの機械。
*Java言語とJavaVMの対応 [#c678bb1f]
-1つのJava言語のクラスは1つのJavaVMのクラスファイルに対応している。
-1つのJava言語のオブジェクトは1つのJavaVMのオブジェクトに対応している。
-1つのJava言語のメソッドは1つのJavaVMのメソッドに対応している。
-1つのJava言語のコンストラクタはJavaVMのメソッドに対応している。
*クラスローダについて [#if35b2ca]
**システムクラスローダ [#uf6ed515]
-1つのJavaVMに1つだけ存在。
-CLASSPATHにて定義。
**ユーザクラスローダ [#fafcc0b6]
-1つのJavaVMに複数存在可能。
-Java.lang.ClassLoaderクラスのサブクラスのインスタンスとして実行可能。
*メモリ上の各エリア [#g8090567]
&ref(http://aslweb.u-aizu.ac.jp/~s1130205/Gallery/MemoryStructure.png);
**メソッドエリア [#d531c79c]
-クラスの置き場
**ヒープ [#u7d890e0]
-インスタンス置き場
**Javaスタック [#u8f20f94]
-スレッド毎に割り当てられる場。
**フレーム [#jf79b6af]
-メソッド呼び出し毎にJavaスタック上に積まれる作業場。
-実行終了時に破棄。
**ローカル変数 [#wb3ad910]
-メソッド上に作られるJava言語のローカル変数とメソッド引数置き場
-サイズはコンパイラにより指定。
-番号により管理されている。
-0番にはthisが入る。
**オペランドスタック [#ic9d2eb5]
-メソッド上に作られるオペランド置き場
-サイズは(ry
*クラスファイル [#i87db6de]
&ref(http://aslweb.u-aizu.ac.jp/~s1130205/Gallery/NestingClassfileStructure.png);
class ClassFile{
u4 magic; //CA FE BA BE
u2 minor_version; //minor version
u2 major_version; //major version
u2 constant_pool_count; // コンスタントプールエントリ配列の要素数
cp_info[] constant_pool = new cp_info[constant_pool_count - 1]; //コンスタントプールエントリ配列
u2 access_flags; //このクラスのアクセスフラグ
u2 this_class; //このクラスへのクラス参照のCPエントリ番号
u2 super_class; //スーパークラスへのクラス参照のCPエントリ番号
u2 interface_count; //実装/継承しているインタフェースのCPエントリ番号配列の要素数
u2[] interfaces = new u2[interfaces_count]; //実装/継承しているインタフェースのCPエントリ番号配列
u2[] fields_count; //フィールド配列の要素数
field_info[] fields = new field_info[fields_count]; //フィールド配列
u2 fields_count; //メソッド配列の要素数
field_info[] methods = new method_info[fields_count]; //メソッド配列
u2 attributes_count; //クラス属性の配列要素数
attribute_info[] attributes = new attribute_info[attributes_count]; //クラス属性の配列
}
**magic number(4 bytes) [#k6eaac9b]
-"''CA FE BA BE''" はJavaクラスファイルの識別子。
**minor_version(2 bytes) [#w1fb7362]
-クラスファイルを生成したコンパイラのバージョン番号。
**major_version(2 bytes) [#mbceae82]
-minor_versionと同じ。
**constant_pool_count(2 bytes) [#b2093914]
-コンスタントプールエントリ配列の要素数。
**constant_pool [#d7c00728]
&ref(http://aslweb.u-aizu.ac.jp/~s1130205/Gallery/InheritanceConstantPoolStructure.png);
-[constant_pool_count -1]個のcp_info構造体が存在する。
-タグバイトによりinfoの構造は変わる。
-infoの構造の詳細は下記を参照。
class cp_info{
u1 tag; //タグバイト
u1[] info; //エントリデータの中身
}
-タグ一覧
|Name|Value(0x)|Description|
|CONSTANT_Utf8|1|Utf8形式に変換されたユニコード文字列|
|CONSTANT_Integer|3|intリテラル|
|CONSTANT_Fload|4|floatリテラル|
|CONSTANT_Long|5|longリテラル|
|CONSTANT_Double|6|doubleリテラル|
|CONSTANT_Class|7|クラスまたはインタフェースへの参照|
|CONSTANT_String|8|Stringリテラル|
|CONSTANT_Feildref|9|フィールド参照|
|CONSTANT_Methodref|a|っクラスで宣言されたメソッドへの参照|
|CONSTANT_InterfaceMethodref|b|インタフェースで宣言されたメソッドへの参照|
|CONSTANT_NameAndType|c|メソッド参照やフィールド参照の名前と型の部分を定義するもの|
***cp_info [#jeee99bb]
-タグによるエントリデータ構造の違いを説明する。
-簡略化のためにcp_infoをスーパークラス、その他をサブクラスとした。
abstract class cp_info{
u1 tag;
}
***CONSTANT_Utf8_info [#t383d801]
-ユニコード文字列をUtf形式で格納するコンスタントプールエントリ。
class CONSTANT_Utf8_info extends cp_info{
u2 length; //バイト長
u1[] bytes = new u1[length]; //文字列データ
}
-CONSTANT_Utf8_infoに格納されるデータ一覧
|データの種類|説明|
|Stringリテラルの文字列データ|Stringリテラルの文字列データ。|
|クラスやインタフェースの完全修飾名|コンスタントプールエントリの所属するクラスファイルで定義されているクラスやインタフェースの完全修飾名。スーパークラスの完全修飾名。extendsまたはimplementsしているインタフェースの完全修飾名。|
|フィールド名|コンスタントプールエントリの所属するクラスファイルのクラスで宣言されたフィールドの名前。コンスタントプールエントリの所属するクラスファイルから参照されている別クラスのフィールドの名前。|
|フィールドディスクリプタ|コンスタントプールエントリの所属するクラスファイルのクラスで宣言されたフィールドのフィールドディスクリプタ。コンスタントプールエントリの所属するクラスファイルから参照されている別クラスのフィールドのフィールドディスクリプタ。|
|メソッド名|コンスタントプールエントリの所属するクラスファイルのクラスで宣言されたメソッドの名前。コンスタントプールエントリの所属するクラスファイルのクラスから参照されている別クラスのメソッドの名前。|
|メソッドディスクリプタ|コンスタントプールエントリの所属するクラスファイルのクラスで宣言されたメソッドのメソッドディスクリプタ。コンスタントプールエントリの所属するクラスファイルのクラスから参照されている別クラスのメソッドのメソッドディスクリプタ。|
|属性名|CodeやConstantValueなどの、属性の名前を表す文字列。|
***CONSTANT_Integer_info [#ud081851]
-int型リテラルを格納するコンスタントプールエントリ。
class CONSTANT_Integer_info extends cp_info{
u4 bytes;
}
***CONSTANT_Float_info [#afc75fe5]
-float型リテラルを格納するコンスタントプールエントリ。
class CONSTANT_Float_info extends cp_info{
u4 bytes;
}
***CONSTANT_Louble_info [#le3650da]
-long型リテラルを格納するコンスタントプールエントリ。
class CONSTANT_Long_info extends cp_info{
u4 high_bytes;
u4 low_bytes;
}
***CONSTANT_Double_info [#a59cc4cc]
-double型リテラルを格納するコンスタントプール。
class CONSTANT_Double_info extends cp_info{
u4 high_bytes;
u4 low_bytes;
}
***CONSTANT_Class_info [#v2f3ff7c]
-クラスまたはインタフェースへの参照を格納するコンスタントプールエントリ。
-配列のクラス(?)もここに当てはまる。
class CONSTANT_Class_info extends cp_info{
u2 name_index; //クラスまたはインタフェースの完全限定名を格納したCONSTANT_Utf8エントリのindex
}
***CONSTANT_String_info [#k07ff1f5]
-Stringリテラルへの参照を格納するコンスタントプールエントリ。
class CONSTANT_String_info extends cp_info{
u2 string_index; //リテラルの値である文字列データを格納したCONSTANT_Utf8エントリへのindex
}
***CONSTANT_Fieldref_info [#oa0678e7]
-フィールドへの参照を格納するコンスタントプールエントリ。
class CONSTANT_Fieldref_info extends cp_info{
u2 class_index; //フィールドの所属するクラスへの参照を格納するCONSTANT_Class_infoのindex
u2 name_and_type_index; //フィールドの単純名とフィールドディスクリプタをまとめたCONSTANT_NameAntType_infoのindex
}
***CONSTANT_Methodref_info [#n247af33]
-クラス(インタフェースではない)で宣言されたメソッドの参照を格納するコンスタントプールエントリ。
class CONSTANT_Methodref_info extends cp_info{
u2 class_index; //メソッドの所属するクラスへの参照を格納するCONSTANT_Class_infoのindex
u2 name_and_type_index; //メソッドの単純名とメソッドディスクリプタをまとめたCONSTANT_NameAndType_infoのindex
}
***CONSTANT_InterfaceMethodref_info [#fe217c4d]
-インタフェース(クラスではない)で宣言されたメソッドへの参照を格納するコンスタントプールエントリ
class CONSTANT_InterfaceMethodref_info extends cp_info{
u2 class_index; //メソッドの所属するインタフェースへの参照を格納するCONSTANT_Class_infoのindex
u2 name_and_type_index; //メソッドの単純名とメソッドディスクリプタをまとめたCONSTANT_NameAndType_infoのindex
***CONSTANT_NameAntType_info [#f465c08d]
-フィールドやメソッドの参照の名前と型をまとめたものを格納するコンスタントプールエントリ。
class CONSTANT_CONSTANT_NameAndType_info extends cp_info{
u2 name_index; //フィールドもしくはメソッドの単純名を格納したCONSTANT_Utf8エントリのindex
u2 descriptor_index; //ふぃ0るどもしくはメソッドのディスクリプタを格納したCONSTANT_Utf8エントリのindex
}
}
**access_flags(2 bytes) [#w9568c8e]
-このクラスのアクセス制限について示しています。
-コンパイラはクラスもインタフェースも共通の構造をもったクラスファイルとして取り扱う。違いはACC_INTERFACEビットが立っているかどうか。
|Name|Bits|Description|
|ACC_PUBLIC|0000 0000 0000 0001|このクラスまたはインタフェースはpublicである|
|ACC_FINAL|0000 0000 0001 0000|このクラスはfinalである。|
|ACC_SUPER|0000 0000 0010 0000|新しい方のinvokesptialのセマンティクスを使う。|
|ACC_INTERFACE|0000 0010 0000 0000|これはクラスではなくインタフェースである。|
|ACC_ABSTRACT|0000 0100 0000 0000|このクラスまたはインタフェースはabstractである。|
**this_class(2 bytes) [#o1d3f75e]
-このクラスへのクラス参照のエントリ番号
**super_class(2 bytes) [#rec0af7b]
-このクラスのスーパークラスへのクラス参照のエントリ番号
**interfaces_count(2 bytes) [#yb875503]
-interfaces配列の要素数。
**interfaces [#wc0d3022]
-interfaces_count個のCONSTANT_Classエントリ番号。
**fields_count [#d8a9e228]
-fields配列の要素数。
**fields [#ma10ae29]
-[fields_count -1]個のfield_info構造体が存在する。
-field_infoの構造の詳細は下記を参照。
***field_info [#m7f7ad1b]
class field_info{
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info[] attributes = new attribute_info[attributes_count];
}
-access_flags(2 bytes)
|Name|Bits|Description|
|ACC_PUBLIC|0000 0000 0000 0001|このフィールドはpublicである。|
|ACC_PRIVATE|0000 0000 0000 0010|このフィールドはprivateである。|
|ACC_PROTECTED|0000 0000 0000 0100|このフィールドはprotectedである。|
|ACC_STATIC|0000 0000 0000 1000|このフィールドはstaticである。|
|ACC_FINAL|0000 0000 0001 0000|このフィールドはfinalである。|
|ACC_VOLATILE|0000 0000 0100 0000|このフィールドはvolatileである。|
|ACC_TRANSIENT|0000 0000 1000 0000|こnフィールドはtransientである。|
-name_index(2 bytes)
--フィールドの単純名を格納するCONSTANT_Utf8エントリのindex
-descriptor_index(2 bytes)
--フィールドディスクリプタを格納するCONSTANT_Utf8エントリのindex
-attributes_counts
--このフィールド上の属性配列の要素数。
-attributes
--属性配列
--ConstantValueとSyntheticのみ。詳しくは下記参照。
***ConstantValue [#oe78aca9]
-staticフィールドの初期値が入る。
class ConstantValue_attribute extends attribute_info{
ConstantValue_attribute(){
attribute_length = 2;
}
u2 constantvalue_index; //フィールドの初期値(リテラル)へのエントリ番号。リテラルの型はフィールドの型により決まる。
}
-フィールドの型と初期値のコンスタントプールエントリ(リテラルの型)
|フィールドの型|初期値のコンスタントプールエントリ|
|int|CONSTANT_Integer|
|short|CONSTANT_Integer|
|char|CONSTANT_Integer|
|byte|CONSTANT_Integer|
|boolean|CONSTANT_Integer|
|long|CONSTANT_Long|
|float|CONSTANT_Float|
|double|CONSTANT_Double|
|String|CONSTANT_String|
**methods_count(2 bytes) [#h095b5ba]
-メソッド配列の要素数。
**methods [#jcb3a083]
-[methods_count -1]個のmethod_info構造体が存在する。
-method_infoの構造の詳細は下記を参照。
***method_info [#d3ac42bb]
class method_info{
u2 access_flags; //(2 bytes)
u2 name_index; //(2 bytes)メソッドの単純名を格納するCONSTANT_Utf8エントリのindex
u2 descriptor_index; //(2 bytes)メソッドディスクリプタを格納するCONSTANT_Utf8エントリのindex
u2 attributes_count; //(2 bytes)このメソッド上の属性配列の要素数
attribute_info[] attributes = new attribute_info[attributes_count]; //属性配列
}
-access_flags
|Name|Bits|Description|
|ACC_PUBLIC|0000 0000 0000 0001|このメソッドはpubicである。|
|ACC_PRIVATE|0000 0000 0000 0010|このメソッドはprivateである。|
|ACC_PROTECTED|0000 0000 0000 0100|このメソッドはprotectedである。|
|ACC_STATIC|0000 0000 0000 1000|このメソッドはstaticである。|
|ACC_FINAL|0000 0000 0001 0000|このメソッドはfinalである。|
|ACC_SYNCHRONIZED|0000 0000 0010 0000|このメソッドはsynchronizedである。|
|ACC_NATIVE|0000 0001 0000 0000|このメソッドはnativeである。|
|ACC_ABSTRACT|0000 0100 0000 0000|このメソッドはabstractである。|
***Exceptions_atrribute (メソッドのみで使われる属性その1) [#ad448cbb]
-throws節で宣言されている例外の情報を格納する属性。
class Exceptions_attribue extends attribute_info{
u2 number_of_exceptions; //例外配列の要素数
u2 exception_index_table = new u2[number_of_exceptions]; //例外配列。throws節で宣言した例外のクラスを表したCONSTANT_Classエントリのindex
}
***Code_attribute [#x3bab4f0]
-インストラクションコードそのものを格納する属性。
class Code_attribute extends attribute_info{
u2 max_stack; //オペランドスタックの上限値
u2 max_locals; //ローカル変数の上限値
u4 code_length; //インストラクションコード列のバイト長
u1[] code = new u1[code_length]; //インストラクションコード列
u2 exception_table_length; //例外ハンドラ配列の要素数
exception_info[] exception_table = new exception_info[exception_table_length]; //例外ハンドラ配列。このメソッドで定義されているすべてのcatchステートメントの情報を配列にして格納したもの。
u2 attributes_count; //属性配列の要素数
attribute_info[] attributes = new attribute_info[attribute_count]; //属性配列
class exception_info{ //例外ハンドラ
u2 start_pc; //ハンドラの有効範囲の始点
u2 end_pc; //ハンドラの有効範囲の終点
u2 handler_pc; //ハンドラが呼ばれたときにジャンプするアドレス
u2 catch_type; //ハンドラのcatchするクラスのCPエントリ番号
}
}
***LineNumbertable_attribute(メソッドのCode属性で使われる属性その1) [#g8bdd82b]
-ソースコードの行番号とインストラクションコード列の対応関係を格納している。
-主にデバックのために使われる。
class LineNumberTable_attribute extends attribute_info{
u2 line_number_table_length; //行番号配列の要素数。
line_number_info[] line_number_table = new line_number_info[line_number_table_length]; //行番号配列。
class line_number_info{ //行番号。
u2 start_pc; //行番号に対応するインストラクションコードの開始位置。
u2 line_number; //行番号。
}
}
***LocalVariableTable_attribute(メソッドのCode属性で使われる属性その2) [#d4153ae6]
-ソースコードのメソッドの中で使われているローカル変数に関する情報を格納している。
-主にデバックのために使われる。
class LocalVariableTable_attribute extends attribute_info{
u2 local_variable_table_length; //ローカル変数配列の要素数
local_variable_info[] local_variable_table = new local_variable_info[local_variable_table_length]; //ローカル変数配列
class local_variable_info{ //ローカル変数
u2 start_pc; //変数のスコープの開始
u2 length; //変数のスコープの終わりまでの長さ
u2 name_index; //変数名を格納するCONSTANT_Utf8エントリ番号
u2 descriptor_index; //変数の型のを格納するCONSTANT_Utf8エントリ番号
u2 index; //対応するJavaVMローカル変数の番号
}
}
***Synthetic_attribute(フィールドとメソッドの両方で使われる属性) [#gf391eac]
-Java言語レベルでインナークラスを使えるようにするために作られた属性。
class Synthetic_attribute extends attribute_info{
}
**attribute_info [#v395fb15]
class attribute_info{
u2 attribute_name_index; //属性名のCPエントリ番号
u4 attribute_length; //属性データのバイト長
u1[] info = new u1[attribute_length]; //属性データ配列。属性の種類により構造が異なる。
}
-下記のクラスをスーパークラスとし、他の属性関係クラスはサブクラスとなる。
abstract class attribute_info{
u2 attribute_name_index; //属性名のCPエントリ番号
u4 attribute_length; //属性データのバイト長
}
***SourceFile_attribute(クラスでのみ使われる属性 その1) [#lca9ecf5]
-ソースファイルに関する情報を格納する属性。
class SourceFile_attribute extends attribute_info{
SourceFile_attribute(){
attribute_length = 2;
}
u2 sourcefile_index; //ソースファイル名を格納したCONSTANT_Utf8エントリのindex
}
***InnerClasses_attribute(クラスでのみ使われる属性 その2) [#f07cbfb9]
-インナークラスに関する情報を格納する属性。
class InnerClasses_attribute extends attribute_info{
u2 classes_count; //インナークラス配列の要素数
inner_class_info[] classes = new inner_class_info[classes_count]; //インナークラス配列
class iner_class_info{ //インナークラス
u2 inner_class_index; //インナークラス参照を格納するCONSTANT_Classエントリのindex
u2 outer_class_index; //アウト-クラス参照を格納するCONSTANT_Classエントリのindex
u2 inner_class_acces_flags; //インナークラスのアクセスフラグビットの集まり。ClassFile構造体のaccess_flagsと共通。
}
}
*Technical term [#v03ff14e]
**ディスクリプタ [#ve4307dc]
-フィールドやメソッドの型を表す文字列。
***フィールドディスクリプタのBNF表記 [#la90806b]
<フィールドディスクリプタ> ::= <data_type>
<data_type> ::= <base_type> | <object_type> | <array_type>
<base_type> ::= B|C|D|F|I|J|S|Z
<object_type> ::= L<fullclassname>;
<array_type> ::= [<data_type>
-プリミティブ型ディスクリプタ
|ディスクリプタ|Java言語の型|
|B|byte|
|C|char|
|D|double|
|F|float|
|I|int|
|J|long|
|S|short|
|Z|boolean|
**メソッドディスクリプタのBNF表記 [#ocd1c010]
-()でくくった部分が引数の型を表す。
-()に続く文字列が返り値の型を表す。
<メソッド> ::= (<argument_types>) <return_type>
<argument_types> ::= <data_type>*
<return_type> ::= <data_type> | V
|ディスクリプタ|Java言語の型|
|V|void|
**クラスローダ [#g26f0b46]
***実行時のクラス合成 [#t03cea40]
-例
c = cl.loadClass("BBDash");
-上記の命令が実行されるとき下記の動作が起こる。
+BBDashクラスをロードしようとする。
+しかし、BBDashクラスのクラスファイルがメソッドエリアにないためClassLoaderクラスのfindLocalClass()が呼ばれる。
+findLocalClass()がBBDashクラスを上位クラスのクラスファイルからバイトコードで読み込み、それをコンソールからユーザ入力に基づいて書き換えてから、そのバイトコードをdefineClass()でメソッドエリアのクラスに展開する。
**コンスタントプールリゾリューション [#w570203d]
-例
new java/lang/StringBuffer
-バイトコードでは
BB xx xx
-とあらわされる。xx xxにはCONSTANT_Classのエントリ番号が入る。
-CONSTANT_ClassはCONSTANT_UTF8エントリ番号を保持しているだけ。
--参照するクラスがメソッドエリアのどのアドレスに格納されているのかという情報をもっていない。
-最初に上記の命令を実行するときにはjava/lang/StringBufferクラスのクラスファイルをメモリにロードし、xx xx番目のコンスタントプールエントリをロードしたクラスへのポインタで置き換える。
**リゾルブ [#u79ad7c8]
-シンボリック参照をポインタに書き換えること。
**コンストラクタ [#h6c9f224]
-オブジェクトを生成する際に必ず実行される初期化処理を記載した部分です。
ページ名: