12

私の知る限り、Java 7にMethodHandleが導入されたことで、コンパイラーによって生成されたメソッドのオーバーロードが導入されました。

MethodHandleのjavadocには、次のように記載されています(例をトリミングしました)。

使用例を次に示します。

Object x, y; String s; int i;
mh = ...
// (Ljava/lang/String;CC)Ljava/lang/String;
// (String, char, char) -> String
s = (String) mh.invokeExact("daddy",'d','n');

// (Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
// (Object, Object, Object) -> Object
x = mh.invokeExact((Object)1, (Object)2, (Object)3);

// (Ljava/util/List;)I
// (List) -> int
i = (int) mh.invokeExact(java.util.Arrays.asList(1,2,3));

// (Ljava/io/PrintStream;Ljava/lang/String;)V
// (PrintStream, String) -> void
mh.invokeExact(System.out, "Hello, world.");

上記の各呼び出しは、invokeという名前とコメントに示されているタイプ記述子を持つ単一のinvokevirtual命令を生成します。引数の型は実際の引数から直接取得されますが、戻り型は呼び出しにすぐに適用されたキャストから取得されます。このキャストはプリミティブへのキャストである可能性があります。欠落している場合、戻り値を使用するコンテキストで呼び出しが発生すると、タイプはデフォルトでObjectになります。呼び出しがステートメントとして発生する場合、キャストは不可能であり、リターンタイプはありません。呼び出しは無効です。

事実上、invokeExactとその仲間は、パラメーターとリターンタイプの可能なすべての組み合わせに対してオーバーロードがあるかのように動作します。

MethodHandlesがラムダのようなJava8の機能を準備していると聞きました。(私はそれらがすでにスクリプト言語に役立つことを知っています。)

[/前書き]

では、これらのコンパイラーによって生成されたオーバーロードがJavaに隠れているのでしょうか?将来(たとえば、拡張メソッドを使用して)さらに多くのヒントがありますか?そもそもなぜそれが必要なのですか?ただのスピード?ラムダをどのように助けますか(ラムダは匿名の内部クラスにコンパイルされると思いました)?

要するに、理論的根拠は何ですか。なぜそれら(生成されたオーバーロード)が現在および将来的に役立つのですか?

更新:ここでコンパイラが生成するオーバーロードと呼んでいるのは、オラクルの連中が署名ポリモフィックと呼んでいることです。

4

2 に答える 2

15

MethodHandlesとinvokedynamicのホットスポット内部ウィキに出くわしました

これらの質問に答えるいくつかの興味深い点(およびさらにいくつか)があります。

  • 質問ではコンパイラ生成のオーバーロードと呼ばれるもので、Javaの連中は署名ポリモーフィックと呼んでいます。
  • MethodHandle.invokeExactと友達はユニークで、唯一のシグネチャーポリモーフィックメソッドです。
  • HotSpot VMでは、invokevirtualMethodHandle.invoke*のバイトコードが密かにinvokehandle命令に変換されます。
    • invokehandleのようなinvokedynamic; いくつかの内部構造は異なり、各invokedynamic命令が独自の定数プールキャッシュエントリ(CPCE)を指す必要がある場合、invokehandlesはCPCEを共有できます。
  • invokedynamicMethodHandle.invokeBasicHotSpotVM で非公開を使用します
    • MethodHandle.invokeBasicinvokeExactに似ていますが、より緩いです。1つは、呼び出し側のタイプを呼び出し先のタイプとチェックしません。
  • ホットメソッドハンドル(を含むinvokedynamic)はJITコンパイルできます

さらに、ラムダ式はを​​介して実装されinvokedynamicます。(Edwin Dalorzoの回答から得ました。)これはラムダ式を意味します

  • MethodHandle.invokeBasicHotSpot VM(上記を参照)で間接的に使用し、
  • JITコンパイルされる資格があります
于 2012-12-22T06:17:43.947 に答える
4

これらの2つのリンクは、すべての質問に答えることはできませんが、出発点として適している場合があります。

これは、現在JDK 8:ProjectLambdaで作業している専門家グループからの参考資料です。運が良ければ、ラムダ式を内部クラスとして誤解していることについて、いくつかの説明を見つけることができます。

于 2012-12-21T12:26:22.090 に答える