2013-06-17 10 views
8

一般的な質問は、次のとおりJava 8でメソッド参照を間接的に実行する方法は?

  • 構文object::aMethodを使用して、それが機能的インターフェイスとしてMethodHandleような型に変換することができますか?
  • いいえの場合、可能であれば、メソッド参照がJava 8で間接的に呼び出される方法を教えてください。

    class MethodRefRunner { 
        static void execute(Object target, WHATTYPE mref, Object... args) { 
        mref.apply(args); 
        } 
    } 
    

    そして、それはとして使用することができます:WHATTYPEのための上記のスニペットではMethodRefRunner.execute(o, o::someMethod, someParam)

    、一つの選択肢である

  • 例として

、我々はMethodRefRunnerようにしたいのですが想像java.util.function.Functionですが、非常に限定的です。 this answerには、バージョンb75より前にはjava.util.function.Blockがあり、便利な場合がありました。

WHATTYPEは何らかの形でjava.lang.invoke.MethodHandleに変換される可能性があります。

注:Javaの専門家に注:必要に応じて質問のタイトルを修正してください。

+1

*メソッド*を*関数値*に強制することができます。これは*η拡張*(Scalaの*メソッド*と*関数*に違いがあります)です。あなたが記述した場合、Scalaコンパイラは両方を受け入れるほどスマートです。 – Beryllium

+0

@Beryllium実際、Java 8がそれを選んでいない理由について私は疑問に思っていました。 – nobeh

+2

@nobeh Java 8は、関数型を追加すると言語にはるかに大きな変更が加えられたため、機能的なインターフェイスが必要です。彼らは後で来るかもしれない。 –

答えて

8

あなたがしたいことをする方法はないと思います。 WHATTYPEは、必ずしもFunctionではない機能的インタフェース—でなければならないが、単一の抽象メソッドがsomemethodと一致するものでなければならない。通常のインタフェース型で、Javaの型を規定する通常の規則に従います。 java.util.function.Blockはこのような通常のインターフェースタイプで、あなたが思っているように特別なものではありません。 Consumerと呼ばれています。と呼ばれています。

+0

答えをありがとう。さて、問題は、メソッド参照(またはラムダ式)を実行時に 'MethodHandle'に変換して呼び出すことができる方法があるかどうかです。 – nobeh

+1

申し訳ありませんが、答えはまだノーだと思います。理由は(AFAIK)そのようにする方法は、特定のラムダ実装の形式で固定の開始点を持つ必要があるということです。しかし、実行時に「動的に内部クラス、メソッドハンドル、動的プロキシ、メソッドハンドルプロキシ、またはその他の未知のメカニズムの周りのラッパークラスを選択できます」という意図は実装を制約することではありません。 (http://mail.openjdk.java.net/pipermail/lambda-dev/2011-November/004224.html)。したがって、実際に何かしたいことがあれば、常にVMに依存します。 –

+0

私はディスカッションスレッドを2012年11月から見つけましたが、これはどこにでも行くことは明らかではありません:http://mail.openjdk.java.net/pipermail/lambda-spec-experts/2012-December/000159.html – Gili

5

メソッド参照はラムダと同じように動作し、ラムダと同様に単独では「型」はありません。そのタイプは、使用されるコンテキストに依存します。だからあなたの質問は本当に意味をなさない。このMethodRefRunner.execute()メソッドへの呼び出しでメソッド参照を使用する場合、メソッド参照のタイプは、WHATTYPEのインスタンス(それが何であれ)になります。これは、メソッドが受け入れると宣言されているためです。他の場所から取得した場合は、その場所はどのタイプか分かります。

関連する問題