4

JDK 7 の新しい invokedynamic バイトコード命令に関するこの投稿を読んで理解したように、オブジェクトのクラスで静的に定義されていないオブジェクトのメソッドを呼び出し、それらのメソッド呼び出しをいくつかの具体的な静的メソッドに解決することが可能になります。メソッド呼び出しのターゲット解決をインターセプトすることにより、他のクラス(投稿に例が示されています)。

これは、Java 7 クラスが Scala のような暗黙のメソッドを持つことができるということですか? そうでない場合、Scala での暗黙的なメソッドの解決は、invokedynamic メソッドの解決とどのように異なるのでしょうか?

4

2 に答える 2

13

まったく無関係です。scala の暗黙はコンパイル時に完全に解決されます。コンパイラは、自分で書いたようなものを挿入します。それができない場合、コンパイル時にエラーが発生します。InvokeDynamic は、実行時にメソッドを見つけ、見つからない場合は実行時に失敗することです。

具体的には、型 x にメソッド m がないところを scala で書くx.m()と、スコープ内にある (この時点で f を呼び出すことができます) という関数である暗黙の変換を探します (この時点で f を呼び出すことができます)。これは x をパラメーターとして受け入れ、結果の型にはメソッドがありmます (ルールにはさらに多くの詳細がありますが、これが本質です)。x.m()そのようなメソッドが見つかった場合、適切に型指定されたに置き換え られますf(x).m()。コードでそのように書くこともできますが、Java ではそうしなければなりません。そのような関数 f が見つからない場合、コンパイル時エラーが発生します。

g(x)を呼び出して、xに渡すのに適切なタイプでない場合も、まったく同じように発生しgます。f適切な型を持つ関数があればf(x)、コードを に置き換えますg(f(x))。繰り返しますが、プレーンな scala で自分で書くこともできますが、そのようなメソッドがなければコンパイルされません。

動的とは、コンパイル時に にメソッドがあるかどうかをあまり気にせず、実行時にmメソッドxを探すことです。これは、JRuby や Groovy などの動的言語が通常どのように機能するかです。scala、trait Dynamic (実験的とマークされています) に関連するものがあります。

于 2011-08-20T21:04:35.483 に答える
5

invokedynamic バイトコードは、JVM での動的言語の高速化に役立ちます。また、Scala の構造型へのアクセスも高速化されます。invokedynamic の代替 (および JDK 7 より前の唯一のオプション) はリフレクションですが、これは非常に低速です。

Java-the-language は静的に型付けされており、invokedynamic を使用する機能はありません ( this questionによると、java.lang.invoke.MethodHandleを使用した明示的なリフレクション メソッド呼び出しは別として)。

Scala の暗黙は実際には静的に解決されるため、invokedynamic とは無関係です。それがどのように機能するかの詳細については、Daniel Sobral の優れた公開を参照してください: Scala は暗黙的なものを探す場所は?

于 2011-08-20T21:03:54.217 に答える