2012-01-10 7 views
5

Пример, показанный в описании MethodHandle класса бросает в вызове заявления mh.invokeExact("daddy",'d','n') с нижеследующим описанием в WrongMethodTypeException: (CC)Ljava/lang/String; cannot be called with a different arity as ([Ljava/lang/Object;)Ljava/lang/Object;.MethodHandle пример бросает WrongMethodTypeException на invokeExact вызова

MethodHandle объект mh имеет дескриптор символического типа, соответствующий: (CC)Ljava/lang/String. Но когда мы вызываем mh.invokeExact("daddy",'d','n'), аргументы: d и n передаются как массив Object, а затем они не соответствуют аргументам типа char.

Я знаю, что я могу решить данную проблему с помощью invokeWithArguments вместо invokeExcat или invoke, но этот пример должен был работать, как представлено в описании MethodHandle в Java 7 API. Кроме того, invokeWithArguments имеет служебные служебные данные по отношению к invoke/invokeExact.

ответ

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

, кажется, работает OK:

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

Видя эту ошибку тоже с OpenJDK 1.7.0_07 на Linux с кодом [этого примера] (http://stackoverflow.com/questions/14146570/calling-a-getter- в-Java-хотя-отражательного Что-The-быстро путь к многократно) –

0

invokeExact требует точного соответствия между описанием типа метода MH и типами аргументов. Поскольку тип метода MH равен (cc)string, так что вы хотите выполнить MH, как первый, так и второй аргумент должен быть char. Таким образом, это похоже, что

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