問題タブ [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.
c# - インターフェイスから RuntimeMethodHandle を取得しますか?
一部のリフレクション コードではうまく機能しない逆アセンブル コードがあります。MethodHandlesなどの操作方法がわからないため、有効にする方法がわかりません...リフレクションの第一人者にとっては非常に簡単な作業であると思います。 「インターフェースからメソッドハンドルを取得する」必要がありますか? 私は正しいですか?
次のパラメーターが間違っています。IProductRepositoryItem.Code は RuntimeMethodHandle である必要があります
完全なコード:
java - MethodHandle の例は、invokeExact 呼び出しで WrongMethodTypeException をスローします
クラスの説明に示されている例では、次の説明を持つステートメントの呼び出しでMethodHandle
a がスローされます。WrongMethodTypeException
mh.invokeExact("daddy",'d','n')
(CC)Ljava/lang/String; cannot be called with a different arity as ([Ljava/lang/Object;)Ljava/lang/Object;
MethodHandle
オブジェクトには、以下mh
に対応するシンボリック型記述子があります(CC)Ljava/lang/String
。しかし、 を呼び出しているときmh.invokeExact("daddy",'d','n')
、引数:d
とn
が配列として渡されObject
、タイプ の引数と一致しませんchar
。
またはのinvokeWithArguments
代わりに を使用して上記の問題を解決できることはわかっていますが、この例はJava 7 APIの説明に示されているように機能するはずでした。それに加えて、 には/に関連するパフォーマンス オーバーヘッドがあります。invokeExcat
invoke
MethodHandle
invokeWithArguments
invoke
invokeExact
java - MethodHandle - それは何ですか?
私は 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 言語機能もあります。
java - オーバーロードされたメソッドのメソッドハンドルを取得する
Java 7でオーバーロードされたメソッドのメソッドハンドルを検索することは可能ですか?
java-7 - 動的ロード クラス オブジェクトで MethodHandle の invokeExact を使用できない
次のようなデモコードがあります。
ここでは「com.hp.ac.scriptengine.test.」+ generateClassName' は生成されたクラスです。以下のようなメッセージが届きました。
ここで 138 行目はmh.invokeExact(my_obj,1);
'
mh.invokeExact("daddy",'d','n')...
Java 7 APIドキュメントでそのデモコード( ... など)を試しました。それは正常に動作します。そのような call( mh.invokeExact("daddy",'d','n')
)(CC)Ljava/lang/String
は、 以外を呼び出すだけです(Ljava/lang/String;CC)Ljava/lang/String
。しかし、なぜ私のコードでmh.invokeExact(my_obj,1)
(I)V 以外の (Ljava/lang/Object;I)V を呼び出すのでしょうか?
java - メソッドハンドル操作
アスペクトJとinvokedynamicを使った作業では、ポイントカットが呼び出されたメソッドと一致するときに、メソッドにアドバイスを織り込む必要があります。最初に、スクリプト内の invokedynamic-instruction のブートストラップ メソッドを独自のものと交換しました。ここで、ブートストラップ メソッドで、呼び出されたメソッドを最初に呼び出す CallSite を返し、その後、定義したアドバイスを返したいと考えています。
問題は、元のブートストラップ メソッドで使用されたものと同じ型シグネチャを持つ 1 つの MethodHandle から CallSite ビルドを返さなければならないことです。2 つのメソッドハンドル (元の + アドバイス) を新しいものに結合し、それを返される CallSite に使用することを考えました。しかし、それを行うための適切な方法が見つかりません。MethodHandles.foldArguments は有望なようですが、私にはうまくいきませんでした。もう 1 つのアイデアは、元のメソッド ハンドルとアドバイスを呼び出すラッパー メソッドから MethodHandle を構築することでしたが、問題は正しい型シグネチャです。
誰か私にアイデアや提案はありますか? アドバイスを使用して MethodHandle にパッチを適用するにはどうすればよいですか?
ありがとうございました。
java-7 - Java-7のシグネチャポリモーフィックメソッドについて
私の知る限り、Java 7にMethodHandleが導入されたことで、コンパイラーによって生成されたメソッドのオーバーロードが導入されました。
MethodHandleのjavadocには、次のように記載されています(例をトリミングしました)。
使用例を次に示します。
上記の各呼び出しは、invokeという名前とコメントに示されているタイプ記述子を持つ単一のinvokevirtual命令を生成します。引数の型は実際の引数から直接取得されますが、戻り型は呼び出しにすぐに適用されたキャストから取得されます。このキャストはプリミティブへのキャストである可能性があります。欠落している場合、戻り値を使用するコンテキストで呼び出しが発生すると、タイプはデフォルトでObjectになります。呼び出しがステートメントとして発生する場合、キャストは不可能であり、リターンタイプはありません。呼び出しは無効です。
事実上、invokeExactとその仲間は、パラメーターとリターンタイプの可能なすべての組み合わせに対してオーバーロードがあるかのように動作します。
MethodHandlesがラムダのようなJava8の機能を準備していると聞きました。(私はそれらがすでにスクリプト言語に役立つことを知っています。)
[/前書き]
では、これらのコンパイラーによって生成されたオーバーロードがJavaに隠れているのでしょうか?将来(たとえば、拡張メソッドを使用して)さらに多くのヒントがありますか?そもそもなぜそれが必要なのですか?ただのスピード?ラムダをどのように助けますか(ラムダは匿名の内部クラスにコンパイルされると思いました)?
要するに、理論的根拠は何ですか。なぜそれら(生成されたオーバーロード)が現在および将来的に役立つのですか?
更新:ここでコンパイラが生成するオーバーロードと呼んでいるのは、オラクルの連中が署名ポリモフィックと呼んでいることです。
java - メソッドハンドルのパフォーマンス
java.lang.invoke.MethodHandle
のパフォーマンスとjava.lang.reflect.Method
メソッドの直接呼び出しをテストする小さなベンチマークを書きました。
MethodHandle.invoke()
私はそのパフォーマンスを直接呼び出しとほぼ同じと読みました。しかし、私のテスト結果は別のものを示しています:MethodHandle
リフレクションより約 3 倍遅い呼び出し。私の問題は何ですか?これは、いくつかの JIT 最適化の結果でしょうか?
環境: Java バージョン "1.7.0_11" Java(TM) SE ランタイム環境 (ビルド 1.7.0_11-b21) Java HotSpot(TM) 64 ビット サーバー VM (ビルド 23.6-b04、混合モード) OS - Windows 7 64
java - java.lang.invoke.MethodHandle でプライベート メソッドを呼び出す
メソッド ハンドルを使用してプライベート メソッドを呼び出すにはどうすればよいですか?
私が見る限り、公的にアクセス可能なLookup
インスタンスは 2 種類しかありません。
MethodHandles.lookup()
MethodHandles.publicLookup()
また、無制限のプライベート アクセスも許可しません。
Lookup.IMPL_LOOKUP
私がやりたいことをしている非公開があります。それを取得する公的な方法はありますか (SecurityManager が許可していると仮定して) ?