首页 » Java程序员修炼之道 » Java程序员修炼之道全文在线阅读

《Java程序员修炼之道》14.2 多语言编程

关灯直达底部

从第5章开始,你已经无数次见证了JVM作为语言运行时平台的奇妙。第1章介绍的OpenJDK项目在Java 7的发布周期中成了Java的参考实现。非常有趣的是JVM已经发展成了一个语言无关的、真正支持多语言编程的虚拟机。

特别是随着Java 7的发布,Java语言丧失了在VM上的特权。平台上的所有语言现在都一视同仁。因此人们对添加之于备选语言非常重要、而对Java本身只有边际效益的VM特性表现出了强烈的兴趣。

这一工作是在达芬奇机(Da Vinci Machine)子项目中开展的,这一项目也叫做mlvm(多语言VM)。在这一项目中培育出的特性会被引入源码主干中。5.5节中的invokedynamic就是这样的例子,但还有很多对非Java语言非常实用的其他特性。也有需要解决的问题。

我们先来看看这些语言特性中的第一个:不同的语言运行在同一个JVM中彼此进行无障碍交流的办法。

14.2.1 语言的互操作性及元对象协议

语言平等是向了不起的多语言编程环境迈出的重要一步,但一些棘手的问题仍然存在。其中主要是不同的语言有不同的类型系统。Ruby的字符串是可修改的,而Java的不可修改。Scala把所有东西都当成对象,即便是在Java里作为原始类型的实体也是如此。

处理这些差异,并为同一JVM内的不同语言提供更好的交互和互操作方式,是目前尚未解决的问题,也是正在积极处理有望近期解决的问题。

想象一个将来要做的Web应用:其核心部分可能是Java代码,Web部分是用Compojure写的(即Clojure),所用的JSON处理类库是用纯粹的JavaScript写的,而你想用ScalaTest中一些很酷的TDD功能来对它进行测试。

这形成了一个JavaScript、Clojure、Scala和Java彼此之间都会直接调用的局面。对JVM语言能够互操作并以一种标准的方式调用彼此对象的需求会随着时间逐渐增强。社区内的广泛共识是需要一种元对象协议(Metaobject Protocol,MOP),以便所有这些语言都能以一种标准的方式工作。MOP可以看做是一种在代码内描述特定的语言如何实现面向对象及相关问题的办法。

要实现这一目标,我们需要想想那些能让某种语言中的对象能在另外一种语言中使用的办法。一种简单的方式是把它转换成其他语言中的本地类型(或甚至在外部运行时中创建一个新的“影子”对象)。这种办法简单,但有严重的问题:

  • 所有语言必须都有一个通用的“主”接口(或超类),语言内的所有类型都必须实现它(比如JRuby中的IRubyObject);
  • 如果用影子对象,那会增加很多内存分配,性能也会受影响。

相反,我们可以考虑为外部运行时构建一个服务作为入口。这一服务会提供一个接口,某一运行时可以通过该接口对外部运行时中的对象执行标准操作,比如:

  • 在其他语言运行时中创建一个新对象并返回对它的引用;
  • 访问(获取方法或设置方法)外部对象的属性;
  • 调用外部对象上的方法,并返回结果;
  • 将外部对象转换成不同的相关类型;
  • 访问外部对象的其他能力,对一些语言来说可能和方法调用的语义有所不同。

在这样的系统中,可以通过在外部运行时上调用navigator来访问外部方法或属性。调用者需要提供一种办法来标识要访问的方法:someMethod。通常是个字符串,但某些情况下也可能是MethodHandle

navigator.callMethod(someObject, someMethod, param1, param2, ...);  

要让这种办法起作用,所有协作语言运行时中的navigator接口必须都一样。实际上,语言之间的真实联系很可能是用invokedynamic建立起来的。

接下来我们去看看多语言JVM和Java 8的模块化子系统组合起来是个什么样子。

14.2.2 多语言模块化

随着Jigsaw和平台模块化的出现,不仅仅是Java才会从模块化中受益(并需要参与进来)。其他语言也能加入其中有所表现。

可以想象,navigator接口及其辅助类很可能会成为一个模块,对某一非Java语言运行时的支持将会由一个或多个模块实现。图14-2中展示了这一模块系统看起来是什么样子。

图14-2 实现了多语言解决方案的模块

如你所见,我们可以用模块系统搭建包含多种语言的应用程序。Clojure模块提供基本的Clojure平台,Compojure模块引入运行webapp所需的组件,包括特定版本的JAR,在别处运行时这些JAR可能会用不同的版本。Scala及其XML也出现了,为了实现Scala和Clojure之间的互操作,Navigator模块也出现了。

在下一节中,我们会讨论非Java语言在平台上的爆炸性涌现所推动的另一个编程趋势:并发。