惊现有人把 OpenJDK 上的 Nashorn dump 下来,使得 Java 7 都能够使用。源代码在 https://bitbucket.org/ramonza/nashorn-backport/

原本 Nashorn 是 Java 8 才有的。如今有人作了向后兼容。好事!

编译源代码

仅仅有源代码没有 jar。要自己编译。没关系非常easy:ant -f make/build.xml。详细步骤先把源代码拖进 Eclipse 项目。然后打开 Ant 视图:

 

点击 + 图标加入 make/build.xml

然后“运行”就可以编译 jar 包,完毕后保存在 dist 文件夹下。

假设大家不能成功编译,给大家一个直接下载地址:http://download.csdn.net/detail/zhangxin09/9398572

測试

測试是否可用:

import javax.script.*;

public class NashornTest {
public static void main(String args[]) {
ScriptEngineManager manager = new ScriptEngineManager();
for (ScriptEngineFactory f : manager.getEngineFactories()) {
printBasicInfo(f);
System.out.println();
} ScriptEngine nashorn = manager.getEngineByName("nashorn");
if(nashorn != null) {
System.out.println("Nashorn is present.");
}
else {
System.out.println("Nashorn is not present.");
}
} public static void printBasicInfo(ScriptEngineFactory factory) {
System.out.println("engine name=" + factory.getEngineName());
System.out.println("engine version=" + factory.getEngineVersion());
System.out.println("language name=" + factory.getLanguageName());
System.out.println("extensions=" + factory.getExtensions());
System.out.println("language version=" + factory.getLanguageVersion());
System.out.println("names=" + factory.getNames());
System.out.println("mime types=" + factory.getMimeTypes());
}
}

检測是否可用的另外一个方法:try{final Class<?> cls = Class.forName("jdk.nashorn.api.scripting.ScriptObjectMirror");} ..

比較 Rhino

创建一个已经封装过的 JS VM

		Nashorn n = new Nashorn();
Object s = n.eval("g={a:1};");
Map ss = (Map)s;
ss.get("a");
System.out.println(ss.get("a").getClass().getName());
System.out.println(s.getClass().getName());

我封装的 api 自己感觉比較顺手,比如:

Map s = n.eval("g={a:1};", Map.class); // js 对象转换为 java map

	        Nashorn n = new Nashorn();
Object obj = n.eval("g=[1, 2, 3];");
System.out.println(obj.getClass().getName()); ScriptObjectMirror so = (ScriptObjectMirror)obj; System.out.println(so.get(0).getClass().getName());

測试观察发现:

js 的 {} 哈希类型会自己主动转为 jdk.nashorn.api.scripting.ScriptObjectMirror。而不是 Rhino 的 NativeObject。但两者都能够转为 Map

js 的 [] 数组类型会自己主动转为 jdk.nashorn.api.scripting.ScriptObjectMirror,而不是 Rhino 的 NativeArray,但能够用 isArray() : boolean 推断是否数组

js 的 Number 类型会自己主动转为 java.lang.Integer。而不是 Rhino 的 Double,这样在处理数字类型时比較方便。

只是这是早期版本号。缺了正式版才有的功能。比如:

if(so.isArray()) {
int[] iarr = (int[])ScriptUtils.convert(so, int[].class); // 转换为 java 数组保存。由于还没有 convert()
}

除了将就还能怎么办涅?想想办法呗(其实也就是谷歌一下)。

public static void main(String[] args) throws ScriptException, IOException {
Nashorn n = new Nashorn();
n.load("C:/project/spring-test/src/com/ajaxjs/framework/config.js");
Object obj = n.eval("g=[1, 2, 3];");
System.out.println(obj.getClass().getName()); ScriptObjectMirror so = (ScriptObjectMirror) obj;
System.out.println(so.get(0).getClass().getName());
if (so.isArray()) {
System.out.println(so);
// int[] iarr = (int[]) ScriptUtils.convert(so, int[].class);
} } /**
* js arr2 java arr
* @param scriptObjectMirror
* @return
*/
public static Object[] toArray(ScriptObjectMirror scriptObjectMirror) {
if (!scriptObjectMirror.isArray()) {
throw new IllegalArgumentException("ScriptObjectMirror is no array");
} if (scriptObjectMirror.isEmpty()) {
return new Object[0];
} Object[] array = new Object[scriptObjectMirror.size()]; int i = 0;
for (Map.Entry<String, Object> entry : scriptObjectMirror.entrySet()) {
Object result = entry.getValue(); if (result instanceof ScriptObjectMirror && scriptObjectMirror.isArray()) {
array[i] = toArray((ScriptObjectMirror) result);
} else {
array[i] = result;
} i++;
} return array;
}

其实,假设你不是强迫症。数组 get(0)/get(1)/... 一样可用,无须转换一次。

单測代码(非常重要!

http://code.taobao.org/p/bigfoot_v2/src/java_v3/test/javascript/TestJS.java

Nashorn 文档:http://cr.openjdk.java.net/~sundar/jdk.nashorn.api/8u20/javadoc/jdk/nashorn/api/scripting/AbstractJSObject.html

Java 7 可执行的 Nashorn,取代 Rhino的更多相关文章

  1. Java 8新特性之 Nashorn(八恶人-6)

    Joe Gage 盖奇·乔 “First time in my life I made a pretty penny.And, figured I'd come home and spend time ...

  2. Java使用Optional与Stream来取代if判空逻辑(JDK8以上)

    Java使用Optional与Stream来取代if判空逻辑(JDK8以上) 通过本文你可以用非常简短的代码替代业务逻辑中的判null校验,并且很容易的在出现空指针的时候进行打日志或其他操作. 注:如 ...

  3. Java JDBC下执行SQL的不同方式、参数化预编译防御

    相关学习资料 http://zh.wikipedia.org/wiki/Java数据库连接 http://lavasoft.blog.51cto.com/62575/20588 http://blog ...

  4. 怎么优化JAVA程序的执行效率和性能?

    现在java程序已经够快的了,不过有时写出了的程序效率就不怎么样,很多细节值得我们注意,比如使用StringBuffer或者StringBuilder来拼接或者操作字符串就比直接使用String效率高 ...

  5. Java SSH远程执行Shell脚本实现(转)

    前言 此程序需要ganymed-ssh2-build210.jar包(下载地址:http://www.ganymed.ethz.ch/ssh2/) 为了调试方便,可以将\ganymed-ssh2-bu ...

  6. 捕获Java线程池执行任务抛出的异常

    捕获Java线程池执行任务抛出的异常Java中线程执行的任务接口java.lang.Runnable 要求不抛出Checked异常, public interface Runnable { publi ...

  7. JAVA 文件编译执行与虚拟机(JVM)简单介绍

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytpo3 java程序的内存分配 JAVA 文件编译执行与虚拟机(JVM)介绍 ...

  8. 浅析java程序的执行过程

    在研究任何一门语言时,无论是面向过程的c,c++(面向过程和面向对象),还是面向对象的.net,java等,弄清语言执行过程至关重要.  何为语言执行过程? 所谓语言执行过程,指对于任何一门语言,如j ...

  9. 通过指令码来判断Java代码的执行顺序(++问题与return和finally的问题)

    问题 在<深入理解Java虚拟机>一书中遇到了如下代码: public int method() { int i; try { i = 1; return i; } catch (Exce ...

随机推荐

  1. 347 Top K Frequent Elements 前K个高频元素

    给定一个非空的整数数组,返回其中出现频率前 k 高的元素.例如,给定数组 [1,1,1,2,2,3] , 和 k = 2,返回 [1,2].注意:    你可以假设给定的 k 总是合理的,1 ≤ k ...

  2. Jquery EasyUI环境下设置下拉框选中指定选项

    前提: 要求点击某个按钮就将所有的下拉框都设置为选中第一个选项,因此,指定索引是最好的做法 尝试过的做法: html代码如下(easyui 的写法) <select class="ea ...

  3. 对“空引用”说bye-bye

    大家可能经常遇到这种情况:当一个对象为null时,调用这个对象的方法或者属性时,就会报错:“Object reference not set to an instance of an object.” ...

  4. 解决:efi usb device has been blocked by the current security policy

    解决:efi usb device has been blocked by the current security policy 问题描述:U盘装系统或者其他操作时,是因为BIOS安全策略,出现上述 ...

  5. Android互动设计-蓝牙遥控自走车iTank

    一.让Android与外部的设备互动 iTank智能型移动平台基本款简介 iTank智能型移动平台是一台履带车,车体上方的控制板有一颗微处理器,我们可以通过它的UART或是I2C接口下达指令来控制iT ...

  6. JS高级——eval

    eval函数可以用来将字符串转换成JavaScript代码并且运行 <script> eval('var a=10'); console.log(a);//10 </script&g ...

  7. Ruby开发环境的搭建

    1.Ruby的下载 https://rubyinstaller.org/downloads/ 2.Ruby的安装 3.Eclipse配置Ruby开发环境 插件地址:http://rubyeclipse ...

  8. Mock随机生成数据模拟后台接口

    <html> <head> <title>测试</title> <script src="http://code.jquery.com/ ...

  9. Xftp 5 和 Xshell 5 基本使用方法

    软件介绍: (1)Xshell: 一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的 TELNET 协议.Xshell通过互联网可以连接到远程的服 ...

  10. flutter 环境搭建

    环境: ladder什么的是必不可少的 win10 + Idea 2019.1.13 + Genymotion 2.12 基本可以在模拟器中运行项目,还有些许小问题,但是可以看到效果了 基本流程 下载 ...