web-dev-qa-db-ja.com

MethodHandle-それはすべて何ですか?

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

はい、オーバーロードに問題があることを認識しています。メソッドを呼び出す場合は、正確なシグネチャを指定する必要があります。オーバーロードされたメソッドを簡単な方法でチェックすることはできません。

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

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

UPDATE-2:私は上のリンクを読み終えました、そこからの引用:

JVMは、すでに動的言語VMであるため、動的言語の構築に最適ですVM。そして、動的言語をファーストクラスのJVM市民に宣伝することにより、InvokeDynamicはそれを証明します。

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

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

パフォーマンスの違いは、いくつかのリフレクトコールを実行するライブラリにとって重要ではない場合があります。特に、それらのコールのほとんどが、通常のコールを実行できるメモリ内に静的構造を動的にセットアップする場合です。しかし、動的な言語では、すべての呼び出しがこれらのメカニズムを使用する必要があるため、パフォーマンスに大きな影響があります。

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

つまり、Javaプログラマーにとっては、本質的に役に立たないのです。私は正しいのでしょうか?この観点から、それはCore Reflection APIの代替方法としてのみ考えることができます。

48
alexsmail

MethodHandlesでできることは、カレーメソッド、パラメーターのタイプの変更、およびその順序の変更です。

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

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

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

33
Peter Lawrey

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

11

MethodHandleは、リフレクションを行うための最新の、より柔軟でよりタイプセーフな方法と考えてください。

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

9
kittylyst