問題タブ [methodhandle]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
2 に答える
2427 参照

java - MethodType は問題ないのに、ここで .invokeExact() を実行できないのはなぜですか?

私のプロジェクトの 1 つで、コンストラクターを動的に呼び出す必要があります。しかし、これは Java 7 であるため、「従来の」リフレクション API ではなく、java.lang.invoke を使用します。

コード:

わかりました、これはうまくいきます。

私が抱えている問題は、次の行にあります。

に置き換えるinvokeinvokeExact、次のスタック トレースが得られます。

よくわかりません。と の両方が引数としてa を持つ単一のコンストラクターを使用するGlobPathMatcherため、 for both は で定義されているものです。そうでなければ、とにかく sを「つかむ」ことはできませんでした。RegexPathMatcherStringMethodTypeCONSTRUCTOR_TYPEMethodHandle

それでも私はWrongMethodTypeException. なんで?


編集:答えを読んだ後のコードは次のとおりです。今は中間マップは必要ありません: aStringを aにマッピングする 1 つのマップが必要ですMethodHandle:

0 投票する
1 に答える
7526 参照

java - MethodHandle::invokeExact をメソッド参照として使用したために発生した LambdaConversionException によって発生した BootstrapMethodError

MethodHandle::invoke または MethodHandle::invokeExact を、MethodHandle を受け入れて生成された出力を返す関数インターフェイスのメソッド参照として使用できるかどうかを確認しようとしていました。

(invoke と invokeExact はシグネチャ ポリモーフィックであるため、InvokeExact でのメタファクトリ呼び出しであることはわかっています。ただし、invoke/invokeExact の適切なバージョンを派生させるために必要だった作業をコンパイラが省略できるかどうかを知りたかったのです。)

呼び出す.InvokeExact0

結果

良いニュースは、メタファクトリ アプローチが機能する機能インターフェイス インスタンスを合成できたことです (印刷されているように: invoke.InvokeExact0$$Lambda$1/1878246837@1be6f5c3 )。悪いニュースは、メソッド参照アプローチが LambdaConversionException を引き起こし、それがさらに BootstrapMethodError を引き起こしたことです。

とにかくメタファクトリの回避策が存在するため、LambdaConversionException のエラーの詳細をどのように解釈することになっているのかを尋ねたいと思います。

0 投票する
0 に答える
58 参照

java - Lambda メソッド参照のためのわかりやすい toString

toStringメソッドハンドルで生成されたラムダを理解できるようにする方法はありますか? Java 8 より前のFunctionバージョンでは、Guava のインターフェースを使用しており、多くのデータ クラスの関数を生成するスクリプトを作成しました。また、クラスとメソッドを明確に識別できるも含めましたtoString。たとえば、「MyItem::getPrice」です。

しかし、Java 8 では、関数の宣言ははるかに簡単になりましたが、関数が何であるかを特定する方法がなくなりました。nice の最も重要な理由はtoStringデバッグ目的ですが、他にもあると確信しています。この情報がリフレクションで利用できればいいのですが、明らかにそうではありません。

このコード スニペット

生産する

ご覧のとおり、操作するラムダ スーパークラスさえありません。

明確化

独自の を定義する方法を尋ねているのではなくtoString、このラムダが呼び出しているクラス/メソッドを特定する方法を尋ねています。自分で定義すると、 toStringJava 8 ラムダを使用する目的全体が無効になります。適切なtoString. ラムダなしで自動化されたスクリプトを使用することもできます。

0 投票する
1 に答える
415 参照

java - MethodHandle InvokeExact パラメータ

メソッド ハンドルのメソッド パラメータがわかりません。まず、以下に示すように、test メソッド ハンドルを使用してガードを作成します。

私にとっての問題は、パラメーターが 3 つのメソッド ハンドル (test、trueTarget、および faliover) にどのように渡されるかということです。1、invokeExact の最初のパラメーター「result」がレシーバーとしてテスト ガードに渡され、2 番目のパラメーター「data」が startWith に渡されます。

But the these three parameters are passed to the falseTarget as:

So, what's the rule for parameters passing and how do they match to the methods referenced by a method handle?

0 投票する
2 に答える
432 参照

java - タイプがクラスローダーによって動的にロードされるオブジェクトの InvokeExact

私はこの問題に一日を費やしました。私の問題は、クラス型がプログラムの実行時に動的にロードされるインスタンスで MethodHandle.invokeExact 呼び出しを行う方法です。問題をより明確にするために、サンプルコードを以下に示します。

このサンプルでは、​​expClass が動的にロードされ、そのクラス タイプはAddSampleです。次の行の obj インスタンスは BaseTemplate であると宣言されており、その実際の型はAddSample. クラス AddSample は BaseTemplate のサブクラスです。次に、メソッドハンドル myMh を add 関数に作成しAddSampleますが、receiverType が一致しないため、myMH の呼び出しは失敗します。

myMH.invokeExact実行時エラーを発生させます

this のレシーバーはmyMHexpClass (AddSample) にあると宣言されてobjいますが、obj のクラスは AddSample ですが、現在提供されているレシーバーは BaseTemaplte と宣言されているためです。InvokeExact では、パラメーターが正確に一致する必要があります。


私の問題は次のように単純化される可能性があります:インスタンスをその基本型から動的にロードされる子型にキャストする方法は?

obj の宣言された型を、動的にロードされる AddSample に変更します..?

UPDATE:

キャストを使用しても、以前の結果と同じ問題を解決するのには役立ちません。その理由は、指定されたパラメーターが myMH 宣言と完全に一致していないためです。生成されたバイトコードを確認すると、より明確になります。

myMH は を指して (AddSample,String,int,float)intいますが、パラメーター: (Object, String, int, float)を指定すると、前に示した実行時エラーが発生します。

ありがとう

0 投票する
1 に答える
185 参照

java - 戻り値の型 (強制キャスト) が MethodHandler のパフォーマンスにおいて重要なルールを果たしているのはなぜですか?

私は単純なプロジェクトに取り組んでおり、Bean プロパティを取得する必要があります。まず、リフレクションを使用します。次に、パフォーマンスを向上させるために、invokedynamic とメソッド ハンドラーについて調査を行いました。

インボークinvokeExactはリフレクションよりもはるかに高速ですが、リフレクションよりもはるかに低速です。

テスト環境:

  • Win7 32ビット
  • ジャワ 7 U 80
  • コアによるCPU 3.06GHZ

私が得たtp / msはこれについてです:

パフォーマンス テストの出力は次のとおりです (2 回実行しました)。

ここに私のテストコードがあります:

invokeExactコンパイル時に正確な戻り値の型がわからないため、ユース ケースを満たすことができません。リターンの型(強制キャスト)がMethodHandleの性能を左右する重要な鍵のようです。

MethodTypeの戻り値の型が正確であるため、これは予期された結果ではないようです。パフォーマンスを向上させるためにフォースキャストを行うことが依然として重要なのはなぜですか?

これに関する詳細を説明するドキュメントはありますか? また、リフレクションとメソッド ハンドラの使用の impl の詳細を比較するドキュメントはありますか?

0 投票する
2 に答える
6073 参照

java - MethodHandle の方が速いのに、なぜリフレクションを使用してクラス メンバーにアクセスするのですか?

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

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

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

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

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