目次 | 前項目 | 次項目 内部クラス仕様


内部クラスは Java Virtual Machine の編成にどのように影響するか?

Java Virtual Machine が処理するクラスファイルフォーマット、または標準クラスライブラリに変更はありません。新しい機能はコンパイラが実装します。バイトコードの構成は、すべての 1.1 準拠コンパイラがバイナリ互換のクラスファイルを生成するのに充分な精度で指定されます。

Java ソースコードの単一ファイルは、多くのクラスファイルについてコンパイルできます。これは新しい現象ではありませんが、強力な内部クラス表記法によって、プログラマは最後には比較的少ないコードで多数のクラスファイルを作成できるようになります。さらに、アダプタクラスはわずかなメソッドで非常に単純になります。これは、多くの内部クラスを使用する Java プログラムが、多くの小さなクラスファイルに対してコンパイルすることを意味します。このようなクラスに対するパッケージ化の技術は、これらクラスを合理的効率的にプロセスします。例えば、サンプルクラス FixedStack.Enumeration のクラスファイルは3/4 キロバイトを占めますが、その 40% はコードを実装するために直接必要です。この比率はファイルフォーマットの調整に応じて、改善されていくでしょう。virtual machine のメモリ使用パターンは互換です。

クラス名の変換

ネストしたクラスの名前は必要に応じて、他のスコープ内の固有の名前と衝突しないようにコンパイラによって変換されます。名前は、ドットで修飾されたソースの形式を取り、クラス名の後の各ドット `.' をドル記号 `$' に変えることによって virtual machine にエンコードされます。(メカニカルトランスレータは Java でドル記号を使用することが許されます。)

クラス名が private またはブロックに対してローカルのとき、これはグローバルにアクセス不可能です。コンパイラは、アクセス可能な親クラス名を前置にして、後ろに `$' セパレータとローカルに一意な 10 進数を付けて、このようなアクセス不可能な名前をコード化する選択をする可能性があります。匿名クラスはこのようにエンコードする必要があります。

そこで、内部クラス pkg.Foo.Bar は、Bar が private メンバまたはローカルクラスの場合、pkg.Foo$Bar という実行名または pkg.Foo$23 のような名前を取ります。実装は、グローバルにアクセス不可能なものでも、デバッガおよび同様のツールが認識できるように、名前のフォーマットを守る必要があります。

変換された名前を定義または使用するクラスファイルはすべて、(1.0 ファイルフォーマットでサポートされるように)変換を記録する属性もまた含みます。これらの属性は virtual machine および 1.0 コンパイラが無視できます。この属性のフォーマットはバイナリ互換の節で説明します。

生成された変数およびメソッドの名前

前述したように、内部クラスが親スコープの変数を使用する場合、名前の式は親インスタンスのフィールドへの参照か、または final ローカル変数の値を提供する、カレントインスタンスのフィールドへの参照に変換されます。代わりに、親インスタンスへの参照は、もっとアクセス可能なカレントインスタンスのフィールドへの参照に変換されます。これらの技術には、コンパイラが内部クラス内の覆い隠されたフィールドを合成することが必要となります。

コンパイラが生成するメンバのもう 1 つのカテゴリがあります。クラス Cprivate メンバ m は、1 つのクラスが他を囲む場合、またはこれらが共通のクラスに囲まれる場合、別のクラスが使用する可能性があります。virtual machine はこの種のグループ化について知らないために、コンパイラは D がメンバ m を読み込み、書き込み、または呼び出しできるように、C のアクセスメソッドのローカルプロトコルを作成します。 これらのメソッドは形式 access$0access$1 などの名前を持ちます。これらは決して public にはなりません。アクセスメソッドは、内部クラスではなくクラスに追加される可能性があるという点で一意です。

すべての生成された変数とメソッドはクラスファイル属性で宣言され、1.1 コンパイラはプログラムが直接これらを参照しないようにできます。

セキュリティの暗示

内部クラス C が親クラス Tprivate メンバ m へのアクセスを要求する場合、m への挿入アクセスメソッドは T を同じパッケージのすべてのクラス K による不当なアクセスに対して開きます。現時点では、このようなアクセスメソッドに関してセキュリティの問題は報告されていません。それは、メソッドをパッケージスコープと共に誤使用することが難しいからです。コンパイラには、アクセスメソッドを作成するとき、可能なループホールの作成を監視するために警告を出すように指示することができます。

クラス N が別のクラス Cprotected メンバである場合、N のクラスファイルはこれを public クラスとして定義します。クラスファイル属性は保護モードビットを正しく記録します。この属性は現在の virtual machine によって無視され、C のサブクラスに対してではなく、すべてのクラスの N に対するアクセスが許されます。もちろん、コンパイラは属性を調べるため、このようなエラーを正しく診断します。これは、悪意のあるユーザが簡単に C というサブクラスを作成し、protected かどうかに関わらず N へのアクセスを得ることができるため、セキュリティホールではありません。

同様に、クラスが別のクラスの private メンバである場合、そのクラスファイルはこれをパッケージスコープを持っていると定義し、属性は本当のアクセス保護を宣言するため、1.1 コンパイラはパッケージ内であっても不注意なアクセスを防ぐことができます。


コンテンツ | 前項目 | 次項目

内部クラス仕様 (HTML generated by dkramer on March 15, 1997)
Copyright (c) 1996, 1997 Sun Microsystems, Inc. All rights reserved
コメントや訂正は john.rose@eng.sun.com 宛てに送ってください。