Solon v3.0.3

脚本评估(运行)

</> markdown

基本知识

Liquor Java 脚本,支持完整的 Java 语法及各语言版本特性(具体,看运行时版本)。脚本代码,可分为两部分:

  • 代码头(用于导入类)
  • 代码主体(用于构建程序逻辑。支持内部类、接口、或记录)

Helloworld:

Scripts.eval("System.out.println(\"hello world\");");

脚本编写提要

  • 可以导入类和静态方法;但不能有包名
  • 使用内部类时不要加 "public" 修饰
  • 使用 CodeSpec::imports 导入表达式需要的类或静态方法;或者在代码里添加 "import" 语句

支持预编译(可以缓存起来)

Execable execable = Scripts.compile("System.out.println(\"hello world\");");

execable.exec();

支持所有 Java 语法特性

  • (1) 支持 Java8,泛型与Lambda表达式等特性
public class TestApp {
    public static void main(String[] args) throws Exception {
        Scripts.eval("""
                //::代码头
                import java.util.ArrayList;
                import java.util.List;
                
                //::代码主体
                List<String> list = new ArrayList<>(); //泛型
                list.add("c");
                list.add("java");
                
                list.stream().forEach(System.out::println); //Lamda 表达式
                """);
    }
}
  • (2) 支持 Java11,var 等特性
public class TestApp {
    public static void main(String[] args) throws Exception {
        Scripts.eval("""
                //::代码头
                import java.util.ArrayList;
                
                //::代码主体
                var list = new ArrayList<String>(); //var
                list.add("c");
                list.add("java");
                
                list.stream().forEach(System.out::println);
                """);
    }
}
  • (3) 支持 Java17,record 等特性
public class TestApp {
    public static void main(String[] args) throws Exception {
        Scripts.eval("""
                //::代码主体
                record Point(int x, int y) {}; //定义内部类、或接口、或记录
                
                Point origin = new Point(12, 34);
                System.out.println(origin);
                """);
    }
}
  • (4) 支持 Java21,switch 模式匹配等特性
public class TestApp {
    public static void main(String[] args) throws Exception {
        CodeSpec codeSpec = new CodeSpec("""
                //::代码主体
                return switch (obj) {
                     case null -> "null";
                     case String s -> "String=" + s;
                     case Number i -> "num=" + i;
                     default -> "未知对象";
                 };
                """)
                .parameters(new ParamSpec("obj", Object.class)) //申明参数
                .returnType(Object.class); //申明返回类型

        Scripts.eval(codeSpec, "1");
        Scripts.eval(codeSpec, 1);
    }
}

支持内部类

public class TestApp {
    public static void main(String[] args) throws Exception {
        CodeSpec codeSpec = new CodeSpec("""
                //::代码主体
                class HelloClass {
                    public String hello() {
                        return "hello";
                    }
                }
                
                HelloClass test = new HelloClass();
                test.hello();
                """)
                .parameters(new ParamSpec("obj", Object.class)) //申明参数
                .returnType(Object.class); //申明返回类型

        Scripts.eval(codeSpec, "1");
        Scripts.eval(codeSpec, 1);
    }
}

如何调试脚本?

因为是 100% 的 Java 语法。所以我们可以使用 Java 开发工具进行调试。

  • 把“代码头”放到一个类的头部
  • 把“代码主体”放到一个静态函数里

这样,就可以调试了。比如,把上面的 (1) 示例转面调试形态就是:

//#代码头#
import java.util.ArrayList;
import java.util.List;

public class TestApp {
    public static void main(String[] args) throws Exception {
        //#代码主体#
        List<String> list = new ArrayList<>();
        list.add("c");
        list.add("java");

        list.stream().forEach(System.out::println);
    }
}