2012-01-10 12 views
5

El ejemplo que se muestra en la descripción de la clase MethodHandle arroja una WrongMethodTypeException en la invocación de la declaración mh.invokeExact("daddy",'d','n') con la siguiente descripción: (CC)Ljava/lang/String; cannot be called with a different arity as ([Ljava/lang/Object;)Ljava/lang/Object;.ejemplo MethodHandle lanza WrongMethodTypeException en invokeExact llamada

El objeto MethodHandlemh tiene un descriptor de tipo simbólico que corresponde a: (CC)Ljava/lang/String. Pero cuando invocamos mh.invokeExact("daddy",'d','n'), los argumentos: d y n se pasan como una matriz Object y luego no coinciden con los argumentos del tipo char.

sé que puedo resolver el problema anterior mediante el invokeWithArguments en lugar de la invokeExcat o la invoke, pero este ejemplo se supone que el trabajo que se presenta en la descripción de la MethodHandle de Java 7 API. Además de eso, el invokeWithArguments tiene una sobrecarga de rendimiento en relación con invoke/invokeExact.

Respuesta

2

¿Cómo estás compilando esto?

Suena sospechosamente como un error conocido de Eclipse para mí.

yo sólo he comprobado con javac y este código:

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(); 
     } 
} 

parece funcionar bien:

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

La parte pertinente de la producción de javap parece cuerdo así:

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  
+0

Al ver este error también con OpenJDK 1.7.0_07 en Linux con el código [de este ejemplo] (http://stackoverflow.com/questions/14146570/calling-a-getter- in-java-though-reflection-whats-the-fastest-way-to-repeated) –

0

invokeExact requiere coincidencia exacta entre la descripción del tipo de método del MH y los tipos de argumentos. Dado que el tipo de método de MH es (cc)string, entonces lo que desea ejecutar el MH, tanto el primer como el segundo argumento deben ser char. Por lo tanto, es como que

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