Преобразование MethodType для MethodHandle для принятия параметров Array Object

Я хочу адаптироваться String.startsWith от (String, String)boolean в (String[])booleanтак что он может принимать String[] параметры, в которых первые два параметра будут сопоставлены с (String, String), Поэтому я написал ниже пример кода:

MethodHandle test =MethodHandles.publicLookup().findVirtual(String.class, "startsWith", MethodType.methodType(boolean.class, String.class));
String[] myArgs = {"result", "data", "sijie"};
MethodHandle adapt = test.asSpreader(String[].class, 2);
System.out.println("Adapt... "+ adapt.type().toString());
System.out.println("Compare Result: "+ adapt.invokeExact(myArgs)); //Expect to return false. 

MethodHandle в String.startsWith адаптирован к адаптации boolean (String[]) вначале. Но результат показывает adapt.invokeExact отказ.

Adapt... (String[])boolean
Exception in thread "main" java.lang.invoke.WrongMethodTypeException: expected (String[])boolean but found (String[])Object
    at java.lang.invoke.Invokers.newWrongMethodTypeException(Invokers.java:349)
    at java.lang.invoke.Invokers.checkExactType(Invokers.java:360)
    at org.bytecode.generation.sample.App.main(App.java:78)

Новый (String[]) Объект в трассировке стека довольно запутанный. Кто-нибудь может дать несколько советов, как это исправить?

Спасибо

Эта проблема может быть абстрактной как: Как адаптировать Methodhandle это только принимает (String, String)boolean так что он может принять (String[])boolean параметры?

2 ответа

Решение

Проблема с invokeExact позвонить - потому что invokeExact является полиморфной сигнатурой, вам нужно явно указать тип возвращаемого значения, используя приведение:

System.out.println("Compare Result: "+ (boolean)adapt.invokeExact(myArgs));

Это то, что трассировка стека пытается вам сказать expected (String[])boolean but found (String[])Object - потому что у вас не было актерского состава boolean, javac Предполагается, что дескриптор метода будет иметь тип (String[])Object, но во время выполнения он имел тип (String[])boolean вместо. (Порядок может быть запутанным. Думайте об этом как "учитывая дескриптор метода, какой тип я ожидаю, чтобы быть записанным во время компиляции для invokeExact?")

Смотрите также мой ответ на Почему я не могу.invokeExact() здесь, даже если MethodType в порядке?, (Этот вопрос включал подтипы и разрешение asType а также добавление актеров, но информация похожа.)

Получил решение после многих попыток.

MethodHandle guard =MethodHandles.publicLookup().findVirtual(String.class, "startsWith", MethodType.methodType(boolean.class, String.class));
String[] myArgs = {"result", "data", "sijie"};
guard.invokeWithArguments(Arrays.copyOfRange(myArgs, 0, guard.type().parameterCount()));
Другие вопросы по тегам