5

クラスの説明に示されている例では、次の説明を持つステートメントの呼び出しでMethodHandlea がスローされます。WrongMethodTypeExceptionmh.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')、引数:dnが配列として渡されObject、タイプ の引数と一致しませんchar

またはのinvokeWithArguments代わりに を使用して上記の問題を解決できることはわかっていますが、この例はJava 7 APIの説明に示されているように機能するはずでした。それに加えて、 には/に関連するパフォーマンス オーバーヘッドがあります。invokeExcatinvokeMethodHandleinvokeWithArgumentsinvokeinvokeExact

4

2 に答える 2

2

これをどのようにコンパイルしていますか?

私には既知の Eclipse バグのように思えます。

javac とこのコードで確認しました:

import java.lang.invoke.*;

public class ScratchMH {    
        private static ScratchMH instance = null;

        public ScratchMH() {
                super();
        }

        private void run() throws Throwable {
                Object x, y; String s; int i;
                MethodType mt; MethodHandle mh;
                MethodHandles.Lookup lookup = MethodHandles.lookup();

                // mt is (char,char)String
                mt = MethodType.methodType(String.class, char.class, char.class);
                mh = lookup.findVirtual(String.class, "replace", mt);
                s = (String) mh.invokeExact("daddy",'d','n');
                // invokeExact(Ljava/lang/String;CC)Ljava/lang/String;

                System.out.println(s);
        }

        public static void main(String[] args) throws Throwable {
                instance = new ScratchMH();
                instance.run();
        }
}

問題なく動作するようです:

ariel-2:src boxcat$ javac scratch/clj/ScratchMH.java 
ariel-2:src boxcat$ java scratch/clj/ScratchMH
nanny
ariel-2:src boxcat$ 

javap からの出力の関連部分も正常に見えます。

  35: invokevirtual #8                  // Method java/lang/invoke/MethodHandles$Lookup.findVirtual:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;
  38: astore        6
  40: aload         6
  42: ldc           #9                  // String daddy
  44: bipush        100
  46: bipush        110
  48: invokevirtual #10                 // Method java/lang/invoke/MethodHandle.invokeExact:(Ljava/lang/String;CC)Ljava/lang/String;
  51: astore_3      
于 2012-01-10T20:07:30.627 に答える
0

invokeExactMH のメソッド タイプの説明と引数のタイプが完全に一致している必要があります。MH のメソッド タイプは(cc)stringであるため、MH を実行したいものは、第 1 引数と第 2 引数の両方を char にする必要があります。というわけで、その通りです

``String s = (String)mh.invokeExact('a', 'b')``
于 2016-08-11T00:48:46.727 に答える