一个类(来自Elasticsearch Rest API)有一个我想要调用的受保护方法。问题是此方法具有方法参考参数:
protected <Req extends ActionRequest, Resp> Resp performRequestAndParseEntity(
Req request,
CheckedFunction<Req, Request, IOException> requestConverter,
CheckedFunction<XContentParser, Resp, IOException> entityParser,
Set<Integer> ignores, Header... headers) throws IOException {
return performRequest(request, requestConverter, (response) ->
parseEntity(response.getEntity(), entityParser), ignores, headers);
}
在API中,这种方法被称为:
DeleteIndexResponse deleteIndexResponse = restHighLevelClient.performRequestAndParseEntity(
deleteIndexRequest,
Request::deleteIndex,
DeleteIndexResponse::fromXContent,
Collections.emptySet(),
headers
);
Java告诉我&#34; 此表达式的目标类型必须是功能界面&#34; DeleteIndexRequest::deleteIndex
和DeleteIndexResponse::fromXContent
。
我的(不工作)解决方案:
java.lang.Class clazz = restHighLevelClient.getClass();
java.lang.reflect.Method performRequestAndParseEntity = clazz.getDeclaredMethod(
"performRequestAndParseEntity",
Object.class,
org.elasticsearch.common.CheckedFunction.class,
org.elasticsearch.common.CheckedFunction.class,
java.util.Set.class,
org.apache.http.Header.class
);
performRequestAndParseEntity.setAccessible(true);
org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse
deleteIndexResponse = (org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse)
performRequestAndParseEntity.invoke(
restHighLevelClient,
deleteByIndexRequest,
org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest::deleteIndex,
org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse::fromXContent,
java.util.Collections.emptySet(),
null
)
;
修改
我还尝试将deleteIndex
(和fromXContent
)投放到CheckedFunction
,即调用invoke
:
performRequestAndParseEntity.invoke(
...,
((org.elasticsearch.common.CheckedFunction) org.elasticsearch.client.Request::deleteIndex),
...
);
我还尝试在invoke
调用之外定义一个变量:
org.elasticsearch.common.CheckedFunction deleteIndexFunction =
org.elasticsearch.client.Request::deleteIndex;
和
org.elasticsearch.common.CheckedFunction deleteIndexFunction =
(org.elasticsearch.common.CheckedFunction) org.elasticsearch.client.Request::deleteIndex;
总而言之,Java告诉我们:&#34; 类型Request没有定义适用于此处的deleteIndex(Object)&#34;,fromXContent
也是如此
有关信息,deleteIndex
的定义方式如下:
static Request deleteIndex(DeleteIndexRequest deleteIndexRequest) {
...
}
CheckedFunction
是:
@FunctionalInterface
public interface CheckedFunction<T, R, E extends Exception> {
R apply(T t) throws E;
}
编辑2
我还尝试使用类似的相同结果对CheckedFunction
对象进行参数化(&#34;类型Request没有定义适用于此处的deleteIndex(DeleteIndexRequest)&#34; ):
org.elasticsearch.common.CheckedFunction<org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest, org.elasticsearch.client.Request, Exception> deleteIndexFunction =
(org.elasticsearch.common.CheckedFunction<org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest, org.elasticsearch.client.Request, Exception>) org.elasticsearch.client.Request::deleteIndex;
我认为问题是deleteIndex
功能不公开。
答案 0 :(得分:0)
Method.invoke
的签名将所有参数声明为Object
,而不管实际的参数类型是什么。这意味着Object
是编译器尝试将方法引用转换为实现的类型,由于Object
不是函数接口,因此无法工作。
要解决此问题,请将每个方法引用转换为它实际应该是的类型 - org.elasticsearch.common.CheckedFunction
。编译器会选择它作为方法引用的预期类型,允许它工作。