簡體   English   中英

評估 java class 中的 groovy 表達式

[英]Evaluate groovy expression in java class

我希望使用 java 代碼中的 groovy 從字符串值評估數學表達式。 我創建了 groovy 腳本,如下所示:

def sum(List<MyObject> myObjList) {
    int sum =0
    myObjList.each {it -> sum += it.grade}
    return sum
}

class MyObject 定義為:

public class MyObject
{
    private String name;

    private String description;

    private double grade;

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getDescription()
    {
        return description;
    }

    public void setDescription(String description)
    {
        this.description = description;
    }

    public double getGrade()
    {
        return grade;
    }

    public void setGrade(double grade)
    {
        this.grade = grade;
    }
}

評估表達式的代碼是:

public class Test
{

    public static void main(String[] args) throws IOException
    {
        List<MyObject> objects = new ArrayList<>();
        MyObject myObject = new MyObject();
        myObject.setGrade(2.0);
        objects.add(myObject);
        myObject = new MyObject();
        myObject.setGrade(1.0);
        objects.add(myObject);
        ClassPathResource resource = new ClassPathResource("/groovy-scripts/functions.groovy",Test.class);
        File file = resource.getFile();
        Binding binding = new Binding();
        GroovyShell shell = new GroovyShell(binding);
        Script script = shell.parse(file);
        binding.setProperty("objects",objects);
        String formula = "sum(objects)";
        Object result = script.evaluate(formula);
        System.out.println(result);
    }
}

當我嘗試運行代碼時,我不斷收到以下異常:

Exception in thread "main" groovy.lang.MissingMethodException: No signature of method: Script1.sum() is applicable for argument types: (java.util.ArrayList) values: [[com.example.MyObject@3081f72c, com.example.MyObject@3148f668]]
Possible solutions: run(), run(), dump(), use([Ljava.lang.Object;), any(), use(java.lang.Class, groovy.lang.Closure)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:71)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:80)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:51)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:157)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:169)
    at Script1.run(Script1.groovy:1)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:574)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:612)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:583)
    at groovy.lang.Script.evaluate(Script.java:210)
    at com.example.Test.main(Test.java:37)

請提出正確的方法來實現這一目標

我正在使用 groovy 來實現main但它離 java 不遠。

我不完全理解你的目標,但這里是最接近我的選擇


選項 1:使用閉包而不是函數

GroovyShell shell = new GroovyShell();

//use undeclared closure variables 
Script functions = shell.parse('''
    sum = {List myObjList ->
        int sum =0
        myObjList.each {it -> sum += it.grade}
        return sum
    }
''');

functions.run(); // all closure variables assigned into binding
functions.getBinding().setProperty("objects", [ [grade: 111], [grade: 222] ]);
Object result = functions.evaluate("sum(objects)");

println("result="+result);

選項 2 - 使用腳本 inheritance

GroovyShell shell_1 = new GroovyShell();

shell_1.parse('''
    def sum (List myObjList) {
        int sum =0
        myObjList.each {it -> sum += it.grade}
        return sum
    }
''', "FUNCTIONS"); // give a class name to parsed script


def cc = new org.codehaus.groovy.control.CompilerConfiguration();
cc.setScriptBaseClass("FUNCTIONS"); // any parsed scripts will extend FUNCTIONS script class
GroovyShell shell_2 = new GroovyShell(shell_1.getClassLoader(), cc);

Binding binding = new Binding();
binding.setProperty("objects", [ [grade: 111], [grade: 223] ]);

Script formula = shell_2.parse("sum(objects)");
formula.setBinding(binding);

Object result = formula.run();

println("result="+result);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM