Nashorn 的高级应用

Nashorn 是一个复杂的编程环境,它被设计为一个强大的平台,用于部署应用程序,并与Java具有极大的互操作性。 让我们来看一些更高级的用于 JavaScript 到 Java 集成的用例,并通过在 Nashorn中 查看一些实现细节来掌握是如何实现的。

从 Nashorn 中调用 Java

由于每个 JavaScript 对象最后都被编译为 Java 类的实例,所以 Nashorn 与 Java 无缝集成也许并不奇怪,尽管在类型系统和语言特性方面有很大的区别。 然而,仍然需要有一些机制来充分利用这种集成。

我们已经看到,我们可以直接从 Nashorn 访问 Java 类和方法,例如:

$ jjs -Dkey=value
jjs> print(java.lang.System.getProperty("key"));
value

让我们仔细看看是如何在 Nashorn 中实现这种支持的。

JavaClass 和 JavaPackage

从 Java 的角度来看, java.lang.System.getProperty("key")表达式有资格访问 java.lang.System 类下的静态方法 getProperty()。作为JavaScript 语法来说,这非常类似于属性链的访问方式,这个链从 java 这个标识符开始,来看下面的例子:

jjs> print(java);
[JavaPackage java] jjs> print(java.lang.System);
[JavaClass java.lang.System]

所以说java是Nashorn 中特定的一个对象用来访问 Java 系统里的包, java被定义为 JavaPackage 的 JavaScript 的类型,Java 类被定义为JavaClass 的JavaScript 的类型,任何顶层包可直接用作包导航对象,以及子包可以被分配为一个 JavaScript 对象。这提供了访问 Java 类的简明语法:

jjs> var juc = java.util.concurrent;
jjs> var chm = new juc.ConcurrentHashMap;

除了导航包对象,还有另一个对象,称为 Java,其中有一些关于它的有用的方法。其中最重要的是Java type()方法,这允许用户查询 Java 类型系统,并获得java类。例如:

jjs> var clz = Java.type("java.lang.System");
jjs> print(clz);
[JavaClass java.lang.System]

如果这个类不在指定的 classpath 中 (例如,使用 jjs 选择 -cp 选项指定),则会抛出 ClassNotFoundException 异常(jjs 会处理为 RuntimeException 异常)。

jjs> var klz = Java.type("Java.lang.Zystem");
java.lang.RuntimeException: java.lang.ClassNotFoundException:
Java.lang.Zystem

在大多数情况下,在 JavaScript 下 JavaClass 类型就像 Java 中的对象一样使用(它们有一点点不同,基本上可以认为它们是Nashorn级别上的类的影像),举例,我们可以使用 JavaClass 从 Nashorn 中直接创建 Java 对象。

jjs> var clz = Java.type("java.lang.Object");
jjs> var obj = new clz;
jjs> print(obj);
java.lang.Object@73d4cc9e jjs> print(obj.hashCode());
1943325854 // Note that this syntax does not work
jjs> var obj = clz.new;
jjs> print(obj);
undefined

JavaScript 和 Java Lambda 表达式

JavaScript 和 Java 之间的互操作性达到了非常深的层次。我们甚至可以使用JavaScript 函数作为 Java 接口的匿名实现(或作为lambda表达式)。 例如,让我们使用一个 JavaScript 函数作为 Callable 接口的一个实例,这个接口只有一个方法 call(),它不需要参数并返回 void。 在 Nashorn 中,我们可以使用 JavaScript 函数作为 lambda 表达式的实现:

jjs> var clz = Java.type("java.util.concurrent.Callable");
jjs> print(clz);
[JavaClass java.util.concurrent.Callable]
jjs> var obj = new clz(function () { print("Foo"); } );
jjs> obj.call();
Foo

正如事实所示,基本上,在 Nashorn 中,JavaScript 函数和 Java lambda 表达式之间没有区别。 正如我们在 Java 中看到的,函数被自动转换为适当类型的对象。让我们看看如何使用 Java 的 ExecutorService 接口在线程池上执行 Nashorn 的 JavaScript 代码。

jjs> var juc = java.util.concurrent;
jjs> var exc = juc.Executors.newSingleThreadExecutor();
jjs> var clbl = new juc.Callable(function (){
\java.lang.Thread.sleep(10000); return 1; });
jjs> var fut = exc.submit(clbl);
jjs> fut.isDone();
false
jjs> fut.isDone();
true

与等效的 Java 代码相比(即便使用 Java 8 中的 lambdas 表达式),样板代码的减少是相当惊人的。 然而,由于使用了 lambda 的方式,存在一些限制。 例如:

jjs> var fut=exc.submit(function (){\
java.lang.Thread.sleep(10000); return 1;});
java.lang.RuntimeException: java.lang.NoSuchMethodException: Can't
unambiguously select between fixed arity signatures
[(java.lang.Runnable), (java.util.concurrent.Callable)] of the method
java.util.concurrent.Executors.FinalizableDelegatedExecutorService↵
.submit for argument types
[jdk.nashorn.internal.objects.ScriptFunctionImpl]

这里的问题是 ExecutorService 有一个重载的 submit() 方法。 一个方法参数为 Callable,另一个重载的方法参数为 Runnable。 不幸的是,JavaScript 函数适用于转换为两种类型(包括 lambda 表达式)。虽然在运行时可以选择其中一个,但不能在它们之间进行选择 ,因此产生了无法“明确选择”的错误消息。

Java Nashorn--Part 5的更多相关文章

  1. Java 7 可执行的 Nashorn,取代 Rhino

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

  2. Learning Java 8 Syntax (Java in a Nutshell 6th)

    Java is using Unicode set Java is case sensitive Comments, C/C++ style abstract, const, final, int, ...

  3. Atitit。Js调用后台语言 java c#  php swing android  swt的方法大总结

    Atitit.Js调用后台语言 java c#  php swing android  swt的方法大总结 1. Js调用后台语言有三种方法1 2. Swt  BrowserFunction 绑定方法 ...

  4. JS代码检查工具ESLint

    前面的话 ESLint是一个JavaScript代码静态检查工具,可以检查JavaScript的语法错误,提示潜在的bug,可以有效提高代码质量,维持前端团队高度一致的编码风格.ESLint不但提供一 ...

  5. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  6. Java 8 的 Nashorn 脚本引擎教程

    本文为了解所有关于 Nashorn JavaScript 引擎易于理解的代码例子. Nashorn JavaScript 引擎是Java SE 8的一部分,它与其它像Google V8 (它是Goog ...

  7. Nashorn 在JDK 8中融合Java与JavaScript之力

    从JDK 6开始,Java就已经捆绑了JavaScript引擎,该引擎基于Mozilla的Rhino.该特性允许开发人员将JavaScript代码嵌入到Java中,甚至从嵌入的JavaScript中调 ...

  8. Nashorn——在JDK 8中融合Java与JavaScript之力

      从JDK 6开始,Java就已经捆绑了JavaScript引擎,该引擎基于Mozilla的Rhino.该特性允许开发人员将JavaScript代码嵌入到Java中,甚至从嵌入的JavaScript ...

  9. java 11 移除的一些其他内容,更简化的编译运行程序,Unicode 10,移除了不太使用的JavaEE模块和CORBA技术,废除Nashorn javascript引擎,不建议使用Pack200 相关api

    移除的一些其他内容 移除项 移除了com.sun.awt.AWTUtilities 移除了sun.misc.Unsafe.defineClass, 使用java.lang.invoke.MethodH ...

  10. Java 8 Nashorn JavaScript

    转自:https://www.runoob.com/java/java8-nashorn-javascript.html Nashorn 一个 javascript 引擎. 从JDK 1.8开始,Na ...

随机推荐

  1. C#.NET常见问题(FAQ)-如何在不同窗体之间传递值

    最简单的方法是在定义窗体的时候就写好几个变量,在实例化Form2的时候,就把这些参数传递过去   或者你也可以定义一个类,然后通过这个类的静态变量交互(注意只能用静态的,因为Form2无法访问Form ...

  2. 【高德地图Android SDK】视频教学

    前两天参加了高德在北航举办的公开课,感觉非常不错.完成老师布置的作业之后,还顺利地拿到了高德开发者认证证书!! 现在来跟大家分享一下,如何快速学习[高德地图Android SDK]的开发.一天包会!连 ...

  3. 微软BI 之SSRS 系列 - 如何实现报表导航 Navigation 和钻取 Drill Down 的效果

    开篇介绍 如何在 SSRS 报表中实现标签导航 Navigation 和向下钻取 Drill Down的效果? 如同下面这个例子一样 - 在页面第一次加载的时候,默认显示是全部地区的销售总和情况,上面 ...

  4. VDP

    Today VMware announced a new version on their backup product vSphere Data Protection. They gave it t ...

  5. Android下雪动画的实现

    原文链接 : Snowfall 原文作者 : Styling Android 译文出自 : hanks.xyz 译者 : hanks-zyh 校对者: desmond1121 状态 : 完毕 这本是一 ...

  6. Qt 使用 net-snmp 包的过程记录

    使用 C/C++ 进行 SNMP 开发,网上比较流行的主要是用 net-snmp 和 snmp++ .在 sourceforge 上以 Qt 和 snmp 为关键词进行搜索,搜到的项目 net-snm ...

  7. 《鸟哥的Linux私房菜》学习笔记0——计算机概论

    一:CPU架构 精简指令集CPU:SPARC系列.PowerPC系列.ARM系列.其中,ARM CPU广泛应用于手机.PDA.导航系统等设备. 复杂指令集CPU:x86架构的CPU,大量用于个人电脑, ...

  8. Tomcat 的 JDBC 连接池

    JDBC 连接池 org.apache.tomcat.jdbc.pool 是 Apache Commons DBCP 连接池的一种替换或备选方案. 那究竟为何需要一个新的连接池? 原因如下: Comm ...

  9. 20160210.CCPP体系具体解释(0020天)

    程序片段(01):01.二级指针.c 内容概要:二级指针 #include <stdio.h> #include <stdlib.h> //01.二级指针: // 1.使用场景 ...

  10. 怎样解决WampServer #1405 - Access denied for user &#39;root&#39;@&#39;localhost&#39; (using password: NO)

    转载请注明出处:http://blog.csdn.net/xingjiarong/article/details/47903227 之前一直在用wampserver,然后环境配置也是正确的,可是过了一 ...