惊现有人把 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. 6.11---@RequestMapping注解的6+2个属性---6.11

    produces:它的作用是指定返回值类型,不但可以设置返回值类型还可以设定返回值的字符编码: consumes: 指定处理请求的提交内容类型(Content-Type),例如application/ ...

  2. Oracle 递归的写法(start with) 以及where条件作用域

    先转一个讲Oracle递归讲得非常透彻的文章: http://blog.csdn.net/weiwenhp/article/details/8218091 前言:嗯,这也是一个前人挖坑,后人来填的故事 ...

  3. Java&Xml教程(三)使用DOM方式修改XML文件内容

    DOM解析方式也可用于修改XML数据,我们可以使用它完成新增元素.删除元素.修改元素值.修改元素属性等操作. 我们的XML文件,内容如下: employee.xml <?xml version= ...

  4. 【译】x86程序员手册10 - 第4章系统架构

    1.1.2 Part II -- Systems Programming 系统编程 This part presents those aspects of the architecture that ...

  5. C# 配置文件ini操作类

    // [ DllImport ( "kernel32" ) ] //private static extern long WritePrivateProfileString ( s ...

  6. 更改计算机名后DB2不能启动的解决方法

    1.找到以下位置目录下相应的文件db2nodes.cfg C:\Documents and Settings\All Users\Application Data\IBM\DB2\DB2COPY1\D ...

  7. centOS7创建python虚拟环境

    参考: 非常棒的2篇博客 https://www.centos.bz/2018/05/centos-7-4-%E5%AE%89%E8%A3%85python3%E5%8F%8A%E8%99%9A%E6 ...

  8. vue项目中使用百度地图的方法

    1.在百度地图申请密钥: http://lbsyun.baidu.com/  将 <script type="text/javascript" src="http: ...

  9. Navicat 导出为 Excel 文件

    1:先选择一个表 再点击导出向导 2:看图   3:选择保存的路径  4:选择字段    5:最后执行吧 

  10. CAD在网页中增加一个射线

    主要用到函数说明: IMxDrawBlockTableRecord::AddRay 向记录中增加一个射线,详细说明如下: 参数 说明 point1 射线上的点1 point2 射线上的点2 js代码实 ...