Java バイト コードでは、すべてのオブジェクトはオブジェクトとして格納されます。必要に応じて、明示的な型チェックが追加されます。たとえば、このJava関数
public Integer getValue(Object number){
int i = ((Number) number).toInt();
return new Integer(i);
}
次のようなバイトコードに変換されます。
(accepts java.lang.Object, returns java.lang.Integer)
-read the first argument as an Object
-if the value is not a Number, raise an exception
-call the virtual method toInt(java.lang.Integer) of the value
and remember the int result
-use the value as an int argument
-instantiate a new java.lang.Integer
-call the constructor(int) of java.lang.Integer on the new number,
getting an Object back
[since the declared return value of Number.toInt is the same
as the return value of our function, no type checking is needed]
-return the value
そのため、未使用の変数の型はコンパイラによって取り除かれます。パブリック フィールドとプロテクト フィールドの型は、そのクラスと共に格納されます。
オブジェクトの実行時の型は、オブジェクトと共に格納されます。C++ では、仮想メソッド テーブルへのポインターです。Java では、ロードされたすべてのクラスのテーブルへの 16 ビット インデックスとして存在します。
Java クラス ファイルは、すべての依存クラスのインデックスを同様のテーブルに格納します。ここにはクラス名のみが格納されます。すべてのフィールドの説明は、このテーブルを指します。
したがって、あなたが書くときString s = new String("abc")
(またはさえString s = "abc"
)、あなたのクラスは以下を保存します:
- 依存関係の表にあるクラス java.lang.String に依存しています。
- 文字列リテラルの表の「abc」
- ID で文字列リテラルをロードするメソッド
- (最初のケースでは) 最初の依存クラス (String) を引数として、最初の依存クラス (String) のコンストラクターを呼び出すメソッド。
- コンパイラは、新しい String を String 変数に格納することが安全であることを証明できるため、型チェックをスキップします。
クラスは、参照されるとすぐにロードすることも、最初に使用するまでロードすることもできます (この場合、依存するクラスとクラス内の ID によって参照されます)。最近は後者が多いと思います。
クラスがロードされると:
-its class loader is asked to retreive the class by its name.
-(in the case of the system loader) the class loader looks
for the corresponding file in the program JAR, in the system library
and in all libraries referenced.
-the byte stream is then decoded into a structure in memory
-(in the case of early loading) all dependent classes are loaded recursively
if not already loaded
-it is stored in the class table
-(in the case of late loading) its static initialiser is run
(possibly loading more classes in the process).
C++ では、すべてのユーザー クラスとほとんどのライブラリが単なる仮想メソッド テーブルと対応するメソッドとしてプログラムに格納されるため、クラスのロードは行われません。すべてのシステム関数 (クラスではない) は、DLL (Windows の場合) または同様のファイルに格納し、実行時にライブラリによってロードできます。明示的な型キャストによって型チェックが暗示される場合、仮想メソッド テーブルで実行されます。また、C++ にはしばらくの間、型チェック メカニズムがなかったことにも注意してください。