Nashorn 简介

1. 引言

本文重点介绍 Nashorn – 从 Java 8 开始,JVM 的新默认 JavaScript 引擎。
许多复杂的技术已被用于使 Nashorn 的性能比其前身 Rhino 高出几个数量级,因此这是一个值得的改变。让我们来看看它的一些使用方式。

本文大部分内容翻译自:https://www.baeldung.com/java-nashorn

2. 命令行

JDK 1.8 包含一个名为 jjs 的命令行解释器,它可用于运行 JavaScript 文件,或者,如果没有参数,则用作 REPL(交互式 shell):

$JAVA_HOME/bin/jjs hello.js
Hello World

这里的文件 hello.js 包含一条指令:

print("Hello world");

相同的代码可以以交互方式运行:

$JAVA_HOME/bin/jjs
jjs> print("Hello world")
Hello world

您还可以通过添加 #!$JAVA_HOME/bin/jjs 作为第一行来指示 *nix 运行时使用 jjs 来运行目标脚本:

#!$JAVA_HOME/bin/jjs
var greeting = "Hello World";
print(greeting);

然后文件可以正常运行:

$ ./hello.js
Hello World

PS: 我在macOS之中把上面的第1行替换成
#!/Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/Home/bin/jjs暂不清楚为什么$JAVA_HOME没有正确认识出来,我猜测我的$JAVA_HOME变量是用户级别的,而直接运行.js可能无法访问到我的用户的变量。

3. 嵌入式脚本引擎

在 JVM 中运行 JavaScript 的第二种可能更常见的方法是通过 ScriptEngine。JSR-223 定义了一组脚本 API,允许一个可插拔的脚本引擎架构,该架构可用于任何动态语言(当然,前提是它有一个 JVM 实现)。

让我们创建一个 JavaScript 引擎:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");Object result = engine.eval("var greeting='hello world';" +"print(greeting);" +"greeting");

在这里,我们创建一个新的 ScriptEngineManager,并立即要求它为我们提供一个名为 nashorn 的 ScriptEngine。然后,我们传递几个指令并获得结果,可以预见的是,结果是一个字符串“hello world”。

4. 将数据传递给脚本

可以通过定义 Bindings 对象并将其作为第二个参数传递给 eval 函数来将数据传递到引擎中:

import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;public class 将数据传递给脚本 {public static void main(String[] args) throws Exception {ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");Bindings bindings = engine.createBindings();bindings.put("count", 3);bindings.put("name", "baeldung");String script = "var greeting='Hello ';" +"for(var i=count;i>0;i--) { " +"greeting+=name + ' '" +"}" +"greeting";Object bindingsResult = engine.eval(script, bindings);System.out.println(bindingsResult);}
}

运行此代码段会产生:“Hello baeldung baeldung baeldung”。

5. 调用 JavaScript 函数

当然,可以从 Java 代码中调用 JavaScript 函数:

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;public class 调用Javascript函数 {public static void main(String[] args) throws Exception {ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");engine.eval("function composeGreeting(name) {" +"return 'Hello ' + name" +"}");Invocable invocable = (Invocable) engine;Object funcResult = invocable.invokeFunction("composeGreeting", "baeldung");System.out.println(funcResult);}
}

这将返回“Hello baeldung”。

6. 使用 Java 对象

由于我们在 JVM 中运行,因此可以在 JavaScript 代码中使用本机 Java 对象。

这是通过使用 Java 对象实现的:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;public class 使用Java对象 {public static void main(String[] args) throws Exception {ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");Object map = engine.eval("var HashMap = Java.type('java.util.HashMap');" +"var map = new HashMap();" +"map.put('hello', 'world');" +"map");System.out.println(map);}
}

7. 语言扩展

Nashorn 的目标是 ECMAScript 5.1,但它确实提供了扩展,使 JavaScript 的使用变得更好一些。

获取javascript中的变量的值

import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleScriptContext;public class NashornTest {public static void main(String[] args) throws Exception {final ScriptEngineManager factory = new ScriptEngineManager();final ScriptEngine engine = factory.getEngineByName("nashorn");final String raw = "I am the raw value injected";final ScriptContext ctx = new SimpleScriptContext();// **This is the inserted line**ctx.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);ctx.setAttribute("raw", raw, ScriptContext.ENGINE_SCOPE);String script = "var result = 'I am a result';";script += "java.lang.System.out.println(raw);";script += "'I am a returned value';";final Object res = engine.eval(script, ctx);System.out.println(ctx.getAttribute("result"));System.out.println(res);}
}

摘自:
https://stackoverflow.com/questions/42338239/access-variable-of-scriptcontext-using-nashorn-javascript-engine-java-8

参考

https://www.baeldung.com/java-nashorn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/187142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

element-ui表格滚动效果,el-table滚动条样式重置

项目首页需要展示一个表格滚动区域&#xff0c;特此来记录一下 HTML <div class"table-box" mouseenter"mouseenter" mouseleave"mouseleave"><el-table :data"tableList" border height"400px" v-loading"…

华为eNSP AR2220路由器配置教程

文章目录 华为eNSP AR2220路由器配置教程基础配置系统初始化设置用户密码配置设备IP地址 接口配置LAN接口配置WAN接口配置 路由配置静态路由配置动态路由协议配置OSPF配置 安全配置防火墙配置 故障排除查看接口状态日志和诊断测试网络连通性 华为eNSP AR2220路由器配置教程 华…

web前端开发简介及门槛、学习路线

1. 什么是web&#xff1f; Web是 world wide web,万维网,广域网,互联网 Web可以理解是网站 2. 什么网站和网页&#xff1f; 网站是由多个网页和其他文件组成的 3. 什么是web的前端和后端&#xff1f; 4.网页的组成&#xff1a; html: 在网页中真实存在的,例如: 文本,输入…

图像img2img任务任务中评估指标

均方误差&#xff08;Mean Squared Error&#xff0c;MSE&#xff09;&#xff1a;计算两个图像像素之间的平均差异的平方。MSE越小&#xff0c;表示两个图像越接近。 均方根误差&#xff08;Root Mean Squared Error&#xff0c;RMSE&#xff09;&#xff1a;MSE的平方根。RM…

编程之外,生活的美好航程

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

回顾Django的第二天

1.http 1.1http请求协议与响应协议 1.1.1简介 http协议包含由浏览器发送数据到服务器需要遵循的请求协议与服务器发送数据到浏览器需要遵循的请求协议。用于HTTP协议交互的信被为HTTP报文。请求端(客户端)的HTTP报文 做请求报文,响应端(服务器端)的 做响应报文。HTTP报文本身…

使用JAVA语言写一个排队叫号的小程序

以下是一个简单的排队叫号的小程序&#xff0c;使用JAVA语言实现。 import java.util.LinkedList; import java.util.Queue; import java.util.Scanner;public class NumberingSystem {public static void main(String[] args) {Queue<String> queue new LinkedList<…

PCB布线为什么不能走直角或锐角-笔记

PCB布线为什么不能走直角或锐角-笔记 摘要一.PCB走线在直角转弯的地方&#xff0c;信号前后部分相互影响这几个理由我们来一一分析一下传输线的直角带来的寄生电容从阻抗的角度来看直角的尖角产生放电或者电磁辐射走线直角的工艺问题 摘要 有一定熟悉画过PCB板的人或者PCB教学…

Linux常用命令——mv命令

文章目录 1. 简介2. 命令格式3. 主要参数4. 常见用法及示例4.1 移动文件4.2 重命名文件4.3 交互式移动文件4.4 强制移动文件4.5 移动多个文件4.6 使用通配符移动文件 5. 注意事项6. 结论 1. 简介 mv 命令在Linux系统中用于移动文件或目录&#xff0c;同时也可以用于重命名文件…

【js】如何在不指定具体属性名,而是通过变量获取属性名,设置一个对象中多层级下的某个属性的值

为了优化这种赋值方式&#xff0c;可以考虑使用ES6的解构和展开运算符。 首先&#xff0c;我们可以使用解构运算符来提取需要赋值的变量&#xff0c;以增加代码的可读性和简洁性&#xff1a; const { ContainerKey, formId } obj; obj[ContainerKey][formId[0]][formId[1]] …

Ubuntu Server 20.04.6下Anaconda3安装Pytorch

环境 Ubuntu 20.04.6 LTS Anaconda3-2023.09-0-Linux-x86_64.sh conda 23.7.4 Pytorch 1.11.0 安装 先创建一个工作环境&#xff0c;环境名叫lia&#xff1a; conda create -n lia python3.8环境的使用方法如下&#xff1a; conda activate lia # 激活环境 conda deactiv…

【Java 基础 - 泛型机制详细解释】

Java 基础 - 泛型机制详解 为什么会引入泛型泛型的基本使用 泛型类泛型接口泛型方法泛型的上下限泛型数组深入理解泛型 如何理解Java中的泛型是伪泛型&#xff1f;泛型中类型擦除如何证明类型的擦除呢&#xff1f;如何理解类型擦除后保留的原始类型?如何理解泛型的编译期检查&…

查看Hive表信息及占用空间的方法

一、Hive下查看数据表信息的方法 方法1&#xff1a;查看表的字段信息 desc table_name; 方法2&#xff1a;查看表的字段信息及元数据存储路径 desc extended table_name; 方法3&#xff1a;查看表的字段信息及元数据存储路径 desc formatted table_name; 方法4&#xff1a;…

NetApp AFF A800:为人工智能、深度学习和大数据分析提供动力

NetApp AFF A800&#xff1a;为发挥混合云的最大优势提供动力 您对数据的掌控能力将决定您能否在数字化时代取得成功。借助作为全球速度最快的企业级 NVMe 闪存存储之一的 NetApp AFF A800&#xff0c;您可以突破性能的限制。通过行业领先的云集成&#xff0c;您可以管理从边缘…

Linux:docker的数据管理(6)

数据管理操作*方便查看容器内产生的数据 *多容器间实现数据共享 两种管理方式数据卷 数据卷容器 1.数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中&#xff0c;可将宿主机的目录挂载到数据卷上&#xff0c;对数据卷的修改操作立刻可见&#xff0c;并且更新数…

Springboot快速整合kafka

kafka的基本了解 kafka也是 目前常用的消息中间件,支持同步与异步通信,和rabbitmq一样,工作模式大概相同,并且被spingboot整合的后的都是 中间件Template的实列化客户端类 ,消费者监听注解为KafkaListener,和RabbitListener和很相似,这些消息中间件使用过后,发现大致都是相同的…

基于AT89C51单片机的节日彩灯门设计

1&#xff0e;设计任务 本设计采用单片机为主控芯片&#xff0c;结合外围电路组成彩灯门的控制系统器&#xff0c;用来控制16个彩色的LED发光&#xff0c;实现彩色亮点的循环移动&#xff1b;通过软件编程实现各种各样的彩色亮点平面循环移动&#xff0c;该彩色控制器可以通过输…

fastapi 后端项目目录结构 mysql fastapi 数据库操作

原文&#xff1a;fastapi 后端项目目录结构 mysql fastapi 数据库操作_mob6454cc786d85的技术博客_51CTO博客 一、安装sqlalchemy、pymysql模块 pip install sqlalchemy -i https://pypi.tuna.tsinghua.edu.cn/simple pip install pymysql -i https://pypi.tuna.tsinghua.edu.…

IDE1007:当前上下文中不存在名称“xxx“

这种在Halcon中直接导出的代码不能直接放程序中&#xff0c;应该在控件中比如一个按钮中&#xff0c;就不会出错了。

【驱动】SPI驱动分析(五)-模拟SPI驱动

简介 模拟SPI驱动是一种软件实现的SPI总线驱动。在没有硬件SPI控制器的系统中&#xff0c;通过软件模拟实现SPI总线的功能。它允许在不修改硬件的情况下&#xff0c;通过GPIO&#xff08;通用输入/输出&#xff09;引脚模拟SPI总线的通信&#xff0c;从而与SPI设备进行数据交换…