3
class A           { void F() { System.out.println("a"); }}
class B extends A { void F() { System.out.println("b"); }}

public class X {
    public static void main(String[] args) {
        A objA = new B();
        objA.F();
    }
}

ここでF()は、動的に呼び出されていますね。

この記事には次

... Java バイトコードは動的メソッド呼び出しをサポートしていません。サポートされている呼び出しモードは、invokestatic、invokespecial、invokeinterface、invokevirtual の 3 つです。これらのモードでは、既知の署名でメソッドを呼び出すことができます。強く型付けされた言語について話します。これにより、コンパイル時に直接いくつかのチェックを行うことができます。

一方、動的言語は動的型を使用します。したがって、コンパイル時に未知のメソッドを呼び出すことはできますが、Java バイトコードではそれはまったく不可能です。

私は何が欠けていますか?

4

5 に答える 5

14

動的呼び出し動的バインディングを混同しています..

最初のものは、実行時にメソッドがオブジェクトに存在するかどうかわからないプログラムをタイプチェッカーが受け入れることを可能にしますが、動的バインディングはオブジェクトの実行時のタイプに従って適切な実装を選択するだけで、静的に維持しますタイプチェック

どういう意味ですか?

あなたの例では、変数Bの実行時の型が;であるため、Java が object の実装を呼び出すことを意味します。aが aであることを知っているため、実行時にメソッド呼び出しが失敗しないため、コンパイルされます (確実に実装されます)。objABB AobjAF

代わりに動的呼び出しを使用すると、呼び出しているオブジェクトのタイプにそのメソッドが含まれていることをコンパイル時にチェックしません。Fもちろん、実行中にメソッドが指定されたオブジェクトで使用できない場合は例外が発生します。

雑学:invokedynamic多くのスクリプト言語が JVM 上で動作するように記述されており、動的呼び出し機能がないため、これらの言語の開発者はスクリプトと実際の JVM の間に中間層を追加する必要があったため、この機能は Java7 で追加されます。リフレクションを使用した動的呼び出しを気にします。もちろん、このアプローチは多くのオーバーヘッドを引き起こします (Grovvy のことを考えてみてくださいMetaClass)。そのため、Sun はそれらを支援することにしました。

于 2010-04-09T16:48:50.783 に答える
1

あなたの例では、ポリモーフィックに B のインスタンスが A のインスタンスのように見えるため、正しいメソッドが呼び出されます。メソッドは、オブジェクトの実行時の型を調べることで見つけることができます。つまり、B; オブジェクト参照のコンパイル時の型とは対照的に、A. もう 1 つの重要な部分はメソッドの署名です。これらは常に一致する必要があります (もちろん多態的に)。

これは、動的言語とは異なります。動的言語では、オブジェクトのコンパイル時間が本質的になく、実行時にすべてを解決する必要があるからです。

于 2010-04-09T16:49:23.110 に答える
1

実際、あなたが見逃しているのは、これが記事で説明されている「invokevirtual」の一部だということです。

メソッドをオーバーライドしているだけで、仮想メソッド テーブルを使用して正しいメソッドを呼び出します。

于 2010-04-09T16:50:20.453 に答える
0

私はあなたの例を「動的」とは呼びませんが、むしろvirtualと呼びます。コンパイル時にメソッド名とシグネチャがわかっているためです(そして、その存在はコンパイラによってチェックされます)。実行時に解決されるのは、そのメソッドに使用される具体的な実装だけです。

「動的」メソッド呼び出しのより適切な例には、リフレクションが含まれます (メソッド クラスを参照)。このようにして、コンパイル タイプで存在が不明なメソッドを実行時に呼び出すことができます (これはアプリケーション コードではなく、フレームワークで広く使用されています)。

あなたが言及した記事は、その点で少し誤解を招くようです。しかし、明示的に呼び出すメソッドのシグネチャがコンパイル時に認識/チェックされている必要があることは事実です。したがって、その意味で、Java は動的ではありません。

于 2010-04-09T16:54:04.907 に答える