问题描述
如何序列化从java ScriptEngine nashorn获得的谓词?或者我如何将jdk.nashorn.javaadapters.java.util.function.Predicate转换为Serializable?
How can i serialize a predicate obtained from java ScriptEngine nashorn? or how can i cast jdk.nashorn.javaadapters.java.util.function.Predicate to Serializable?
以下是这种情况:
我有这个类
import java.io.Serializable;
import java.util.function.Predicate;
public class Filter implements Serializable {
private Predicate<Object> filter;
public Predicate<Object> getFilter() {
return filter;
}
public void setFilter(Predicate<Object> filter) {
this.filter = filter;
}
public boolean evaluate(int value) {
return filter.test(value);
}
}
和
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.function.Predicate;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class TestFilterSer {
public static void main(String[] args) throws ScriptException {
Filter f = new Filter();
//This works
//f.setFilter(getCastedPred());
// But I want this to work
f.setFilter(getScriptEnginePred());
System.out.println(f.evaluate(6));
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("pred.ser")))) {
oos.writeObject(f);
} catch (IOException e) {
e.printStackTrace();
}
f= null;
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("pred.ser")))) {
f= (Filter)ois.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(f.evaluate(7));
}
public static Predicate<Object> getCastedPred() {
Predicate<Object> isEven = (Predicate<Object> & Serializable)(i) -> (Integer)i%2 == 0;
return isEven;
}
public static Predicate<Object> getScriptEnginePred() throws ScriptException {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
Predicate<Object> p = (Predicate<Object> & Serializable)engine.eval(
String.format("new java.util.function.Predicate(%s)", "function(i) i%2==0")
);
return p;
}
}
要求:成为能够序列化从Nashorn引擎获得的谓词。
Requirement: To be able to serialize the Predicate obtained from Nashorn engine.
观察:当我从方法getCastedPred()获得Predicate时。它的工作原理是因为它是 java.util.function.Predicate
。它在转换为 Serializable
后进行序列化。但是当我从Nashorn引擎获得谓词时,它会在内部返回 jdk.nashorn.javaadapters.java.util.function.Predicate
这个没有序列化和施放到 Serializable
不起作用。
Observation: When I get Predicate from method getCastedPred(). It works because it is java.util.function.Predicate
. it does Serialize after casting to Serializable
. But when I get the Predicate from the Nashorn engine, Internally it returns me the jdk.nashorn.javaadapters.java.util.function.Predicate
this one doesn't Serialize and casting to Serializable
doesn't work.
我知道如何序列化这种类型谓词?
Any idea how can i serialize this type of Predicate?
推荐答案
问题是你的API使用Predicate,而不是AggregateFilter。所以lambda的目标类型在
The problem is your API uses Predicate, not AggregateFilter. So the target type for the lambda in
setAggregatePredicate(x -> true)
将 Predicate
,而非 AggregateFilter
- 并且编译器不会知道它是否可序列化。如果您更改API以使用更具体的功能接口,则将生成可序列化的lambda。
will be Predicate
, not AggregateFilter
-- and the compiler won't know to make it serializable. If you change your API to use the more specific functional interface, serializable lambdas will be generated.
这篇关于如何序列化谓词< T>来自java 8中的Nashorn引擎的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!