【发布时间】:2018-05-02 17:03:30
【问题描述】:
我收到要在运行时用作 biPredicate 的函数的名称。我想传递这个 biPredicate 并评估,基本上是过滤以获得结果。 以下是我定义双谓词的实用程序。我尝试使用 MethodHandle 和 Lambda 函数。当我使用
new FilterUtility().execute("genericFilter");
我得到 java.lang.AbstractMethodError
public class FilterUtility {
public void execute(String filterName) throws Throwable {
ActualBean beanObject = ActualBean.builder().param1("true").param2("false").build();
MethodType methodType = MethodType.methodType(boolean.class, Object.class, Object.class);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle handle = lookup.findStatic(FilterUtility.class, filterName, methodType);
BiPredicate<Object, Object> f = (BiPredicate<Object, Object>) LambdaMetafactory.metafactory(lookup,
"test",
MethodType.methodType(BiPredicate.class),
methodType.generic(),
handle,
methodType)
.getTarget()
.invokeExact();
resolve(beanObject, new HashMap<>(), f);
}
public static <SourceObject, TemplateObject> Map<String, String> resolve(SourceObject src,
TemplateObject template,
BiPredicate<SourceObject, TemplateObject> p) {
if (p.test(src, template))
return new HashMap<>();
return null;
}
public static <SourceObject, TemplateObject> boolean genericFilter(SourceObject x, TemplateObject y) {
ObjectMapper ob = new ObjectMapper();
Map<String, Object> source = ob.convertValue(x, Map.class);
Map<String, Object> template = ob.convertValue(y, Map.class);
for (Map.Entry<String, Object> entry : template.entrySet()) {
if (!source.get(entry.getKey()).equals(entry.getValue()))
return false;
}
return true;
}
}
当我将执行的实现更改为以下时,我没有收到异常。
public void execute(String filterName) throws Throwable {
ActualBean beanObject = ActualBean.builder().param1("true").param2("false").build();
resolve(beanObject, new HashMap<>(), FilterUtility::genericFilter); }
这让我相信我试图找到具有名称的函数并将其作为双向谓词发送的方式有问题。
【问题讨论】:
-
一旦我在这里创建方法句柄
MethodHandle handle = lookup.findStatic(FilterUtility.class, filterName, methodType);,我使用调试器停止,然后我执行handle.invoke(order, new HashMap<String, String>());它给了我java.lang.UnsupportedOperationException。消息:MethodHandle.invoke 不能被反射调用 -
删除第 12 行中的
.generic()。
标签: java reflection lambda functional-programming functional-interface