Javaの多型の実装

ポリモーフィズムを実現するJava

クラスファイルのコンパイルプロセスは、従来のコンパイラでのカップリング工程を含んでいない、すべてのメソッド呼び出しはシンボリック参照クラスファイルではなくメモリレイアウト内のアドレスエントリの実際の操作方法よりも、内部に格納されています。容量のより強力な動的な拡張をもたらすために、この機能Javaは、クラス操作中に特定の目的への直接参照の方法を決定することを可能にする、動的リンク、クラスローディングフェーズにおいて初めて使用されるか、または引用された方法のさらに署名された部分と呼ばれます直接参照に変換されたとき、この変換は、静的な解像度と呼ばれています。

そこにプログラムが実際に実行する前に、メソッド呼び出しのバージョンを決定することができており、実行時にこのメソッドのバージョンを呼び出し不変である:という前提の上に成り立っ静的解像度。言い換えれば、構文解析と呼ばれる、このようなメソッドを呼び出すと、コンパイラの時点で確定ターゲットを起動する必要があります。

Java言語では、「不変で実行するコンパイラ・ショー」に沿ったもので、この方法は、外部から直接アクセスすることはできません前者のタイプ、関連付けられた2つのカテゴリに分類され、主に静的メソッドとプライベートメソッド、両方の方法が必要です継承によって、またはそうでなければ不可能再書き込み他のバージョンにので、それらは、クラスローディング段階で好適に解決されます。

すなわち、4バイト命令のメソッド呼び出しの合計を提供するJava仮想マシン:

invokestatic:静的メソッドを呼び出します。

invokespecial:インスタンスのコンストラクタ・メソッド、プライベートメソッドと親クラスのメソッドを呼び出します。

INVOKEVIRTUAL:すべての仮想メソッドを呼び出します。

invokeinterface:コール・インタフェース・メソッドは、実行時にこのインタフェースのオブジェクトを決定します。

    限りメソッドが呼び出さinvokestaticとinvokespecialコマンドは、四つのカテゴリーには、それらはクラスにロードされる静的メソッド、プライベートメソッド、インスタンスコンストラクタとメソッド親クラスの条件に沿って、唯一の解決フェーズと呼ばれるバージョンで決定することができることができるよう分析方法のための直接参照シンボル参照。これらの方法は(この方法はさらに、最終的を含む)は、非仮想メソッドと呼ぶことができる、対照的に、別の方法は、(最終的なメソッドを除く)仮想メソッドと呼ばれています。ここでは、INVOKEVIRTUALコマンドを使用して、最終的な呼び出し方法が、最終的に下の方法を説明しなければなりませんが、それはカバーできないので、他の受信者の多状態の選択を送信する必要があり、他のバージョンではありませんので。Java言語仕様は明らかに、最終的な方法は、非仮想メソッドで示しています。

メソッドテーブルやメソッドの呼び出し

次のように人、グリル、ボーイカテゴリを定義する場合

クラス人{

パブリック文字列のtoString(){

戻る「私は人間です。」;

}

 

公共のボイド(食べます){

}

 

公共ボイド話します(){

}

 

}

 

クラスボーイ延び人数{

パブリック文字列のtoString(){

戻る「私は男の子ですよ」

}

 

公共ボイド話します(){

}

 

公共ボイド戦い(){

}

}

 

クラスの女の子は、拡張人を{

パブリック文字列のtoString(){

戻る「私は女の子ですよ」

}

 

公共ボイド話します(){

}

 

公共のボイド(歌います){

}

}

 

これらの三つのクラスは、Java仮想マシンにロードされている場合、メソッド領域は、各クラスに関する情報が含まれています。次のように処理ゾーンにおける少年グリルおよび方法テーブルを表すことができます。

あなたは、女の子見ることができるボーイオブジェクトテーブルから継承されたメソッドは、その新たに定義されるの直接の親のPersonの方法や方法から継承されたメソッドが含まれています。このような、特定の方法にメソッドテーブルエントリポイントアドレスことに留意されたいガールから継承されたオブジェクトのメソッドのみのtoString()その実現(ガールズポイントのメソッド・コード)、残りが向けられるオブジェクト・メソッド・コードと、それにから継承された人の方法食べる()および()話すポインティング実装方法及び実装自体。                    

サブクラスは親メソッド、サブクラス同じ名前とテーブルエントリを共有するスーパークラスメソッドのメソッドを書き換えた場合。

したがって、オフセットメソッドテーブルは常に固定されています。メソッドテーブルサブクラスは、親クラスで定義されたオフセット方法が常に一定の値である、すべての親クラスを継承します。

Person 或 Object中的任意一个方法,在它们的方法表和其子类 Girl 和 Boy 的方法表中的位置 (index) 是一样的。这样 JVM 在调用实例方法其实只需要指定调用方法表中的第几个方法即可。

如调用如下:

当编译Person类的时候,生成girl.speak()的方法调用假设为:

Invokevirtual #12

设该调用代码对应着 girl.speak(); #12 是 Person 类的常量池的索引。JVM 执行该调用指令的过程如下所示:

(1)在常量池中找到方法调用的符号引用 。
(2)查看Person的方法表,得到speak方法在该方法表的偏移量(假设为15),这样就得到该方法的直接引用。 

(3)根据this指针得到具体的对象(即 girl 所指向的位于堆中的对象)。
(4)根据对象得到该对象对应的方法表,根据偏移量15查看有无重写(override)该方法,如果重写,则可以直接调用(Girl的方法表的speak项指向自身的方法而非父类);如果没有重写,则需要拿到按照继承关系从下往上的基类(这里是Person类)的方法表,同样按照这个偏移量15查看有无该方法。

おすすめ

転載: www.cnblogs.com/kexinxin/p/11546350.html
おすすめ