Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java MethodHandle示例在调用invokeExact时抛出错误的MethodTypeException_Java_Jvm_Java 7_Invokedynamic_Methodhandle - Fatal编程技术网

Java MethodHandle示例在调用invokeExact时抛出错误的MethodTypeException

Java MethodHandle示例在调用invokeExact时抛出错误的MethodTypeException,java,jvm,java-7,invokedynamic,methodhandle,Java,Jvm,Java 7,Invokedynamic,Methodhandle,MethodHandle类描述中显示的示例在调用语句mh.invokeExact(“daddy”,“d”,“n”)时抛出一个ErrorMethodTypeException,描述如下:(CC)Ljava/lang/String;不能使用不同的arity([Ljava/lang/Object;)Ljava/lang/Object;调用 MethodHandle对象mh有一个符号类型描述符,对应于:(CC)Ljava/lang/String,参数:d和n作为对象数组传递,然后它们与char类型的参数

MethodHandle
类描述中显示的示例在调用语句
mh.invokeExact(“daddy”,“d”,“n”)
时抛出一个
ErrorMethodTypeException
,描述如下:
(CC)Ljava/lang/String;不能使用不同的arity([Ljava/lang/Object;)Ljava/lang/Object;
调用

MethodHandle
对象
mh
有一个符号类型描述符,对应于:
(CC)Ljava/lang/String
,参数:
d
n
作为
对象
数组传递,然后它们与
char
类型的参数不匹配


我知道我可以使用
invokeWithArguments
而不是
invokeExcat
invoke
来解决上述问题,但是这个示例应该按照Java 7 API的
MethodHandle
的描述工作。此外,
invokeWithArguments
的性能超过了与
invoke
/
invokeExact

相关的head是如何编译的

对我来说,这听起来像是一个已知的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      

invokeExact
需要MH的方法类型描述和参数类型之间的精确匹配。由于MH的方法类型是
(cc)string
,因此要执行MH,第一个和第二个参数都应该是char。因此,它是这样的

``String s = (String)mh.invokeExact('a', 'b')``

在linux上的OpenJDK 1.7.007中也看到了这个bug