33

Java 7 のリリースに伴い、MethodHandleユーザーはメソッドを基になるバイトコードを使用しているかのように呼び出すことができます。特に、このMethodHandles.Lookupクラスは、クラス メンバーにアクセスするためのメソッド ハンドルを作成するファクトリ メソッドを提供します。

Lookup オブジェクトのファクトリ メソッドは、メソッド、コンストラクタ、およびフィールドのすべての主要なユース ケースに対応しています。ファクトリ メソッドによって作成された各メソッド ハンドルは、特定のバイトコード動作と機能的に同等です。

機能的には、これはリフレクションを使用してこれらの同じクラス メンバーにアクセスするのとほぼ同等ですが、メソッド ハンドルはリフレクションよりも高速です

それで、まだリフレクション機能を使用する理由はありますかField#get(..)/Method.invoke(..)またはこれらのメソッドは、より高速なメソッドハンドルの導入により事実上廃止されていますか?

メソッドハンドルは Java 7 で導入されましたが、私の質問は主に Java 8 に関するものであることに注意してください。Java 8 では、直接フィールド/メソッド呼び出しとほぼ同等のパフォーマンスに達するように最適化されており、リフレクションの能力を上回っています。

4

2 に答える 2

40

リフレクションとメソッド ハンドルは異なる目的を果たし、異なる抽象化レベルに存在します。解決しようとしている問題に適したものを使用する必要があります。

リフレクションは汎用のイントロスペクション メカニズムであり、クラス ( Class.getMethods()) のメンバーの列挙、アクセシビリティ フラグなどのメンバーの特性の検査、メンバーのジェネリック シグネチャの検査など、メソッド ハンドル メカニズムにはない多くの機能が含まれています。 .

さらに、リフレクティブ オブジェクトは、呼び出しごとにアクセス チェックが行われるため、共有先にアクセスを許可しなくても自由に共有できます。一方、メソッド ハンドルを共有すると、共有対象に呼び出し機能が付与されます。そのため、セキュリティへの影響も異なります。

メソッド ハンドルは、メソッドを検索、適応、および呼び出すための低レベルのメカニズムです。メソッド ハンドルを介した呼び出しは、リフレクションを介した呼び出しよりも高速ですが (現時点では、バイトコードの直接呼び出しはメソッド ハンドルの呼び出しよりも一般的に高速です)、メソッド ハンドルは、Java ユーザーが期待する適応を自動的に実行しないため、使用するのも非常に困難です ( String 引数を Object に変換するなど)、リンケージ エラーが発生します。

リフレクション ライブラリは主流の Java ユーザーを対象としています。メソッド ハンドル層は、コンパイラと言語ランタイムの作成者を対象としています。ジョブ用に設計されたツールを選択します。

于 2015-06-06T02:48:08.283 に答える