博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java Nashorn--Part 5
阅读量:5024 次
发布时间:2019-06-12

本文共 3307 字,大约阅读时间需要 11 分钟。

Nashorn 的高级应用

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

从 Nashorn 中调用 Java

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

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

$ jjs -Dkey=valuejjs> 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@73d4cc9ejjs> print(obj.hashCode());1943325854// Note that this syntax does not workjjs> 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();falsejjs> 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 methodjava.util.concurrent.Executors.FinalizableDelegatedExecutorService↵.submit for argument types[jdk.nashorn.internal.objects.ScriptFunctionImpl]

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

转载于:https://www.cnblogs.com/IcanFixIt/p/6407008.html

你可能感兴趣的文章
jsp题库 (一)小测(25/21)
查看>>
D - Flip tile
查看>>
Java连接RabbitMQ之创建连接
查看>>
开户vim编程之--cscope支持
查看>>
python数据类型图解
查看>>
js获取标准北京时间
查看>>
DZ!NT论坛 3.6.711删除用户各种错解决方案
查看>>
C#微信登录-手机网站APP应用
查看>>
HTML5实践 -- iPhone Safari Viewport Scaling Bug
查看>>
1.4 - 数据类型/字符编码练习题
查看>>
JAVAWEB 一一 Hibernate(框架)
查看>>
函数式编程基础(F#,JS)
查看>>
IntelliJ IDEA使用教程
查看>>
将ASP.NET页面内的数据导出到Excel 或 Word中
查看>>
unity入门笔记
查看>>
html5的cavans
查看>>
闰年测试
查看>>
JSP笔记(一)
查看>>
Android工具HierarchyViewer 代码导读(1) -- 功能实现演示
查看>>
Java基础——多态
查看>>