首页 > 编程语言 >Java 动态编译工具 Janino 和 Liquor 差别

Java 动态编译工具 Janino 和 Liquor 差别

时间:2024-09-24 09:35:16浏览次数:11  
标签:Java String Liquor 编译 Janino void public

如果你只要 Java7 及以下的语法支持,建议 Janino。如果要你想更全的 Java8、Java11、Java17、Java21 等语法,可以选 Liquor。

1、它们相同的地方

  • 提供的相似的能力接口
接口 Janino Liquor
动态编译器 SimpleCompiler DynamicCompiler
表达式评估器 ExpressionEvaluator LiquorEvaluator (Exprs)
脚本评估器 ScriptEvaluator LiquorEvaluator (Scripts)
  • 都是 Java 语言(语法)的动态应用。生成的字节码都可以完全访问 JRE,可能要注意安全的控制。

2、细节区别处

  • Janino 基于自已的编译能力实现。
    • 支持 Java7 及以下语法。
    • 单次编译性能,更好。
    • 支持命令行编译。
    • 提供更丰富的功能。比如代码分析器,等。
  • Liquor 基于 JDK 自带的编译能力实现。
    • 支持 Java8、Java11、Java17、Java21 等语法(由运行时版本决定)。
    • 单次编译性能,差些。
    • 不支持命令行编译。可用 javac 命令。

3、具体差异 - 动态编译器

动态编译器的性能,基本上可以按“次”计量。次数越多,费时越多。尽量把可知代码,合在一起编译(次数,越少越好)。

  • Janino
public class JaninoTest {
    public static void main(String[] args) throws Exception {
        //此类,不可以复用(可以通过别的方式,实现多类一起编译)
        SimpleCompiler compiler = new SimpleCompiler();
        
        String className = "HelloWorld";
        String classCode = "public class HelloWorld { " +
                "   public static void helloWorld() { " +
                "       System.out.println(\"Hello, world!\"); " +
                "   } " +
                "}";
        
        //只能单个编译
        compiler.cook(classCode);
        
        //再 cook ,则会异常

        Class<?> clazz = compiler.getClassLoader().loadClass(className);
        clazz.getMethod("helloWorld").invoke(null);
    }
}
  • Liquor
public class LiquorTest {
    public static void main(String[] args) throws Exception{
        //可以复用(可以,不断的增量编译)
        DynamicCompiler compiler = new DynamicCompiler();
        
        String className = "HelloWorld";
        String classCode = "public class HelloWorld { " +
                "   public static void helloWorld() { " +
                "       System.out.println(\"Hello, world!\"); " +
                "   } " +
                "}";
        
        //可添加多个源码
        compiler.addSource(className, classCode);
        compiler.build();
        
        //构建后,仍可添加不同类的源码再构建

        Class<?> clazz = compiler.getClassLoader().loadClass(className);
        clazz.getMethod("helloWorld").invoke(null);
    }
}

4、具体差异 - 表达式评估器

比较 Janino Liquor
缓存 无(可以自己包装) 有二级缓存(类加载器缓存,编译结果缓存)
体验 每次要重新构建 方便
性能 单次更好 缓存命名时,非常好(接近原始 Java 代码性能)
  • Janino
public class JaninoTest {
    public static void main(String[] args) throws Exception {
        //每次要新实例化
        ExpressionEvaluator ee = new ExpressionEvaluator(); 
        ee.cook("3 + 4"); 
        System.out.println(ee.evaluate()); 
    }
}
  • Liquor
public class LiquorTest {
    public static void main(String[] args) throws Exception {
        //单例,可复用,线程安全
        System.out.println(Exprs.eval("3 + 4"));
    }
}

5、具体差异 - 脚本评估器

比较 Janino Liquor
缓存 无(可以自己包装) 有二级缓存(类加载器缓存,编译结果缓存)
体验 每次要重新构建 方便
性能 单次更好 缓存命名时,非常好(接近原始 Java 代码性能)
  • Janino
public class JaninoTest {
    public static void main(String[] args) throws Exception {
        //每次要新实例化
        ScriptEvaluator se = new ScriptEvaluator(); 
        se.cook("System.out.println(\"hello word\");"); 
        se.evaluate();
    }
}
  • Liquor
public class LiquorTest {
    public static void main(String[] args) throws Exception {
        //单例,可复用,线程安全
        Scripts.eval("System.out.println(\"hello word\");");
    }
}

标签:Java,String,Liquor,编译,Janino,void,public
From: https://www.cnblogs.com/noear/p/18428398

相关文章

  • Java——图片文件位于 bin 目录下,下载新图片会导致应用程序重启
    当应用程序在运行时需要加载图片文件时,如果图片文件位于bin目录下,下载新图片会导致应用程序重启,这是因为Java应用程序在加载资源时通常会遵循以下机制:类加载器:Java应用程序使用类加载器来加载类文件和资源。资源加载:类加载器会根据类路径(classpath)来查找资源,而bin目录......
  • DC00013基于jsp servlet javabeen鲜花销售管理系统网上花店含配套报告
    1、项目功能演示DC00013基于jsp+servlet+javabeen鲜花销售管理系统网上花店网站鲜花销售网上花店管理系统2、项目功能描述 基于jsp+servlet+javabeen鲜花销售管理系统分为用户和系统管理员两个角色。2.1用户功能1、系统登录、系统注册2、主页、产品信息、联系我们3......
  • JavaScript引入到文件的三种方式
    直接嵌入到HTML文件当中利用script标签,将js文件引入到HTML文件中<body><script>varnum=10;</script><!--在Script标签中写入js语句--></body>引入本地独立的js文件 首先命名一个由.js为后缀的文件,然后在HTML文件中使用Script标签......
  • Java实现加法计算器
    今天我们来做一个Java中的方法的小练习:建立一个方法,去实现加法运算。代码实现importjava.util.Scanner;publicclassmethod01{ publicstaticvoidmain(String[]args){ Scannersc=newScanner(System.in); doubleinputNumber1=0.0; doubleinputNumber2=0.0......
  • java中的构造方法
    //1.使用面向对象的思想,编写自定义描述狗的信息。设定属性包括:品种,年龄,心情,名字;//1)设置构造函数实现对属性赋值构造方法的作用:1.可以用来创建对象2.可以用来给对象赋值注意事项:一般来说,如果我们创建了一个有参的构造参数,同时也要创建一个无参的构造参数classDog{......
  • Vue开发前端图片上传给java后端
    前端效果图1前端代码<template><div><!--页面标题--><h1class="page-title">图片上传演示</h1><divclass="upload-container"><!--使用van-uploader组件进行文件上传,v-model绑定fileList数据,支......
  • JavaScript语法特点
    let用来声明变量数组可通过数组名直接输出数组全部元素数组名.length可以返回长度NaN为数字型字符串可用单引号,双引号,反引号进行包裹字符串用反引号包裹,才可以使用模板字符串字符串.replace(正则,替换字符串)返回的是新字符串'',0,undefined,null,false,NaN布尔值都是false未......
  • Java 枚举六种常用的方法详解(超详细讲解)
    目录Java枚举  知识点  概念  枚举的方法  枚举的特性  枚举的应用场景  EnumSet和EnumMapJava枚举知识点概念enum的全称为enumeration,是JDK1.5中引入的新特性。在Java中,被enum关键字修饰的类型就是枚举类型。形式如下:enumColor{RED,......
  • java项目之基于springboot框架开发的景区民宿预约系统的设计与实现(源码+文档)
    项目简介基于springboot框架开发的景区民宿预约系统的设计与实现的主要使用者分为:管理员的功能有:用户信息的查询管理,可以删除用户信息、修改用户信息、新增用户信息,根据公告信息进行新增、修改、查询操作等等。。......
  • JAVA多线程
    一、并发和并行    并发:同一时刻,多个指令在单个CPU上交替执行。    并行:同一时刻,多个指令在多个CPU上同时执行。二、多线程的实现方式1.继承Thread类的方式进行实现。publicclassThreadDemo{publicstaticvoidmain(String[]args){MyT......