MethodHandle示例在invokeExact调用时抛出WrongMethodTypeException

时间:2012-01-10 12:15:07

标签: java jvm java-7 invokedynamic methodhandle

MethodHandle类的描述中显示的示例在语句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')时,参数:dn作为Object数组传递,然后它们与类型{{1}的参数不匹配}}

我知道我可以使用char代替invokeWithArgumentsinvokeExcat来解决上述问题,但此示例应该按照invoke的说明进行操作Java 7 API的{1}}。除此之外,MethodHandle的性能开销与invokeWithArguments / invoke相关。

2 个答案:

答案 0 :(得分:2)

你是如何编译的?

对我来说,这听起来像一个已知的Eclipse bug。

我刚用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      

答案 1 :(得分:0)

div#ext-gen264要求MH的方法类型描述与参数类型完全匹配。由于MH的方法类型是invokeExact,所以你想要执行MH,第一个和第二个参数都应该是char。因此,就像那样

(cc)string