本文介绍了如何序列化谓词< T>来自java 8中的Nashorn引擎的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何序列化从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.

这篇关于如何序列化谓词&lt; T&gt;来自java 8中的Nashorn引擎的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 20:56