52

私は JDK 1.7 の新機能を研究していますが、MethodHandle が何のために設計されているのかわかりません。静的メソッドの (直接的な) 呼び出し (およびこの場合は簡単な Core Reflection API の使用) を理解しています。仮想メソッド(非静的、非最終)の(直接)呼び出し(およびクラスの階層を通過する必要があるコアリフレクションAPIの使用)も理解していますobj.getClass().getSuperclass()。非仮想メソッドの呼び出しは、前者の特殊なケースとして扱うことができます。

はい、オーバーロードに問題があることは承知しています。メソッドを呼び出したい場合は、正確な署名を提供する必要があります。オーバーロードされたメソッドを簡単にチェックすることはできません。

しかし、MethodHandle とは何ですか? リフレクション API を使用すると、(インターフェイスの実装など) 前提条件なしでオブジェクトの内部を「調べる」ことができます。何らかの目的でオブジェクトを検査できます。しかし、MethodHandle も設計されているのは何ですか? なぜ、いつ使用する必要がありますか?

更新:私は今、このhttp://blog.headius.com/2008/09/first-taste-of-invokedynamic.htmlの記事を読んでいます。それによると、主な目標は Java 言語自体ではなく、JVM 上で実行されるスクリプト言語の生活を簡素化することです。

更新-2:上記のリンクを読み終えました。そこからの引用:

JVM は動的言語の VM であるため、動的言語の構築に最適な VM になります。InvokeDynamic は、動的言語を第一級の JVM 市民に推進することで、それを証明します。

リフレクションを使用してメソッドを呼び出すと、うまく機能します...いくつかの問題を除いて。メソッド オブジェクトは特定の型から取得する必要があり、一般的な方法では作成できません。<...>

...反映された呼び出しは、直接呼び出しよりもはるかに遅くなります。何年にもわたって、JVM は反映された呼び出しを高速化することに非常に長けてきました。最新の JVM は実際には、バックグラウンドで一連のコードを生成して、古い JVM で処理されていたオーバーヘッドの多くを回避しています。しかし、単純な真実は、完全に生成された「invoke」メソッドがレシーバーの型、引数の型、可視性、およびその他の詳細をチェックおよび再チェックする必要があるため、任意の数のレイヤーを介したリフレクト アクセスは常に直接呼び出しよりも遅くなるということですが、また、引数はすべてオブジェクトでなければならず (プリミティブはオブジェクトボックス化されるため)、すべての可能なアリティをカバーする配列として提供される必要があるため (引数は配列ボックス化されるため)。

いくつかのリフレクト呼び出しを行うライブラリでは、パフォーマンスの違いは問題にならない可能性があります。特に、それらの呼び出しが、通常の呼び出しを行うことができるメモリ内の静的構造を動的に設定するためのものである場合は特にそうです。しかし、すべての呼び出しでこれらのメカニズムを使用する必要がある動的言語では、パフォーマンスが大幅に低下します。

http://blog.headius.com/2008/09/first-taste-of-invokedynamic.html

したがって、Java プログラマーにとっては、基本的に役に立ちません。私は正しいですか?この観点からは、Core Reflection API の代替手段としか考えられません。

UPDATE-2020:確かに、MethodHandle は Core Reflection API のより強力な代替手段と考えることができます。JDK 8 以降では、それを使用する Java 言語機能もあります。

4

4 に答える 4

34

MethodHandles でできることは、カリー メソッドであり、パラメーターの型を変更し、その順序を変更します。

メソッド ハンドルは、メソッドとフィールドの両方を処理できます。

MethodHandles が行うもう 1 つのトリックは、(ラッパー経由ではなく) プリミティブ ダイレクトを使用することです。

MethodHandles は、インライン化できるなど、JVM でより直接的なサポートがあるため、リフレクションを使用するよりも高速になる可能性があります。これは、新しい invokedynamic 命令を使用します。

于 2012-01-11T17:37:54.140 に答える
11

java.lang.reflect.Methodメモリの点で比較的遅く、高価です。メソッド ハンドルは、JVM が最適化する可能性のある関数へのポインターを渡す "軽量" な方法であると想定されています。JDK8 の時点では、メソッド ハンドルは十分に最適化されておらず、ラムダは (内部クラスのように) クラスに関して最初に実装される可能性があります。

于 2012-01-11T17:34:36.087 に答える
11

MethodHandle は、リフレクションを行う最新の、より柔軟で、より型安全な方法と考えてください。

現在、ライフサイクルの初期段階にありますが、時間の経過とともに、リフレクションよりも高速になるように最適化される可能性があり、通常のメソッド呼び出しと同じくらい高速になる可能性があります。

于 2012-01-11T19:44:14.700 に答える