JDK 的特性又一次推迟了!

  • Alex Blewitt
  • 马国耀

2010 年 9 月 16 日

话题:Java语言 & 开发架构

在一篇题为《重新思考 JDK7》的博文(以及jdk7-dev的跨站转贴)中,Mark Reinhold 提出了将先前计划在 JDK7 中实现的某些特性推迟到 JDK8 的建议,以期 JDK7 的早日面世。该建议是好是坏?在社区里引起了广泛的讨论。

当人们已经接受到 JDK 的推迟已经导致了早前声明的时间表的拖延(当然,这个时间表是无论如何也无法实现的)之后,目前讨论的焦点是是否要提前推出一个版本,还是等到万事 俱备时才发布。Mark 的建议是:

就目前我们对“B 计划”的评估来看,我们可以在 2011 年中期发布简化版的 JDK7,然后在 2012 年下半年发布 JDK8。

总结如下:

  • A 计划:2012 年中期发布 JDK 7(按照目前的定义)
  • B 计划:2011 年中期发布 JDK 7(除去 Lamba、Jigsaw 和 Coin 的一部分)
  • B 计划:2012 年后期发布 JDK 8(Lambda、Jigsaw 和剩下的 Coin 等)

颇具讽刺的是,Mark 的博客的副标题是“刻不容缓!”。然而,从对该博文的回复看,好几个回帖都认为早发布、频繁发布比一次性发布好。虽然人们更期望 B 计划中的某些特性,而对另外一些则差一些,但是毫无疑问,B 计划中的 Coin 项目将对 Java 语言带来极大的好处。Joseph D. Darcy 对 Coin 的特性澄清如下:

B 计划还包含jsr166y 类 (ForkJoin、TransferQueue、Phaser 等) 。此外,它还对 JVM 做了一些改进,如对动态调用JSR292的支持将出现在 JVM 这一层。虽然对于静态类型的 Java 语言,它的用处似乎不大,但它可用来优化当前使用的 Method.invoke() 方法(当在 RMI 或其他企业服务器使用时)。如果这一特性还包含对 MethodHandle 的语言支持,那么在 Java 类中调用函数将方便很多,因为不再需要通过反射机制查找名称正确的消息(MethodHandle 的底层使用 invokedynamic,但需要更改 JLS,所以 B 计划有可能包含 invokedynamicVM 指令和 MethodHandle 类,但不包含对文字的支持)。

在 JVM 上实现其他语言的人们应该为该时间表的更改感到兴奋,因为 invokedynamic 可用的日期更早了,他们不再需要等到 2012 年了。(不过,两个计划都将 Lambda 等放到了 2012 年)。对于同时工作在基于 JVM 的 JRuby 上的 Mirah 的 Charles Nutter,对于这一改变,他只能苦中寻乐

对我所做的工作而言,函数处理也许是即将到来的 JDK7 的最重要的特性之一。对于所有希望无需生成单个方法类就能描述函数或函数指针的 JVM 语言的人们而言,这无疑会成为关键的一部分(因为,当前所有的 JVM 语言必须要做这个工作,若不是在这里,就是在那里)。但是它们的推迟则意味这像 JRuby 这样的语言实现不得不依然要苦苦挣扎,构建前所未有的聪明的代码来生成策略才能躲过内存溢出(或避免吃掉过多的内存)。该特性发布的越早越好。

所以,我该不该心甘情愿地放弃 Jigsaw、Lambda 和 Coin 呢?Jigsaw 和 Coin 也许还能,即便它们一定会(JDK7 中)缺失。而对于 Lambda 而言……如果它不能在短期内完成实际函数类型、整合函数处理与动态调用,它就应该等到这一切都完备了才发布出来。这么说,我是很难过的,但是我们的确有 JVM 上的其他语言可以完成那个闭包(closure),比如我自己的 JRuby 和 Mirah(Mirah 偶尔可以提供闭包 [closure] 甚至更多功能,而不需要任何运行时库或 JVM 的支持)。对我们而言,JVM 的匿名内部类依然很棒(如果你看看 JRuby 的代码库……你会发现数以百计这样的应用)。

对了,对于鼓吹 Scala 的人……请解释一下 Scala 如何解决 B 计划中可能缺失的那些特性。没错,它有自己的闭包(closure),但是它们不能与其他语言或正则 Java 代码进行互操作(除非你相应地限制你的设计),这样一来,除了 Scala 程序员,它们对于其他人它就没什么用处了。它们没有完成 Jigsaw 目标的能力。而且, (我相信)Scala 所提供的大部分 Coin 的特性都已经提供了。Scala 不会成为 Java 语言作为 JVM 的替代品,永远不可能。

甚至有些人认为,尽早发布,频繁发布的频率应该更高。尽管 Java 6 的存在已经有一段时间了,其版本模式却隐藏了这段时间内 VM 上进行的一些重大改变。Osvaldo Pinali Doederlein写道

主要原因当然是 JDK6.1。我一直在跟随“后 -6uN”的发布,在这些发布中 Sun/Oracle 不断地扩展 Java 6 的包裹,在不破坏其 TCK 的同时不断进行改进。我已经对 6u23 的第一次构建进行了测试,(除了一些 Swing 的补丁外)它还带来了另一重大的 VM 的更新,目前已抵达最尖端的 HotSpot 19 了(在当时看来是 JDK7 的最新技术)。它包括了 JDK 7 中如此尖端的特性,譬如,最新的 G1 收集器、对 JSR-292 完整的 VM 支持,以及其他诸如 64 Gb 堆的 CompressedOops、CMS 补丁和数千万的更小的虚拟机 / 运行时补丁以及改进。

版本数在一定程度上是一个比较随性的东西。Sun 多次更改 J2SE/JavaSE 的版本模式,总是会引起世界上至少一半人的反对。有些人认为 6u10 应该称为 6.1。以此类推,我重新做了如下命名:6u14->6.2, 6u18->6.3, 6u21->6.4 and 6u23->6.5。这样说我们可能会觉得好过一些:“好吧,JDK7 又推迟了,见鬼去吧!……但至少我们还有 6.5!”

推迟的另一好处是,这样就能正确地完成该做的事情,而不需要匆匆忙忙敷衍了事。Lambda 项目和核心 Java 库中有些冲突的地方(例如,如何在短期内改造 Collections 类,以使之能利用 Lambda 的优势),这种冲突在短期内可能会引起问题。通过为 Lambda 项目争取更多时间,就可在 JDK8 中解决这些问题,而不会耽误 JDK7 的发布。不单如此,最新的提案中全面删除了 Java 中的函数类型(早前在 InfoQ 中已经提到这事)。由于到有了更多的时间,曾经有人呼吁重新考虑这个决定。可是,首要问题是,删除它的原因尚不明确(类型系统的问题?亦或是时间的问题?),它能否回来同样不明朗。

Jigsaw 也是一样。Jigsaw 是 JDK 在模块系统方面的一个尝试。虽然 OSGi 长期以来作为 Java 在模块系统方面的标准,但是 Jigsaw 试图从拆分 JVM 库和 Java 库的角度重新缔造轮子。Qwylt试图将二者统一,但是正如某些地方提到的,事实上,JVM 和 Java 库的目标完全不同。从这个角度,从 Java 库中分离出 JVM 的 C 计划将是最好的。这样,诸如 IO、NIO、NNIO、NNNIO 之类的库就能按照自己的步伐进行升级了,而不再需要依赖于 JVM+Java 库的综合版的每次更新了。

Peter Kriens写道

Java 正在遭到一个错误的观念的缓慢破坏——“Java 平台越大越好”。可是,更大意味着更多的内部依赖,而依赖来又快速地带来了平台的复杂度。绳索越多,死结也就越多。一次次推迟时间表就是一个征兆。

模块化是让我们既能拥有蛋糕,又能吃蛋糕的唯一的机制。如果 Java 包括一个核心的 Java 平台,那么我们就能轻易地以独立模块的形式加入 JSR 的实现。如果我从不使用 Swing,我的平台为什么要包含它呢?也许在另一个版本中我可能会使用它。将 JSR 模块化可能会让小应用变得复杂,但是,在任何实际的应用中,处理外部依赖的工作已经成为繁杂生活的一部分了。其复杂的原因在于,Java 无论如何也不能解决某些依赖。

我们所需的是一个最小的、能真正理解模块的核心平台。这个最小的 Java 不再把所有的 Javax 包打在一起,而只应该包含良好地定义的核心包和一个能够正确处理来自(远程)存储库的机制,该机制保证了向桌面应用和服务器增加新库的任务变得简单。Perl 能做到、Ruby 能做到、Python 也可以做到,为何 Java 做起来就那么艰难呢?还是兑现承诺,做得更好一点儿吧。

我们的确拥有技术,所有部件都在那儿。Oracle,这次推迟是一个好机遇,我们能让 Java 再一次敏捷起来吗?

在这次简短的申明中,Oracle 正在考虑将一些早前计划在 JDK7 中实现的某些特性推迟,因为它们将问题转变成政变。大量支持“尽早发布,频繁发布”的评论使得他们有勇气在 JavaOne 上正式宣布推迟的计划而且宣称社区是支持他们的。(如果他们单单在 Lambda-Dev 邮件列表中申明,他们收到的反对声音一定会多于支持的声音。)同时,这也给了 Java 平台一个希望,让它有更多的时间让一些不太完善的类(Lambda)变得成熟并且考虑一些东西是否必要(如 Jigsaw)。有一件事是肯定的:将问题公之于众,Oracle 终于理解了社区意见的价值。


查看英文原文:JDK7 Feature Slip

Java语言 & 开发架构