<Java 2007:新年展望>一文中看到一些关于Java 7的消息, 虽然我不是一个Java粉丝, 但Java 7中将带来的一些新的特性还是很让人兴奋的:

期待 Java 7

Dolphin 不会在 2007 年发布。2008 年是更为现实的目标。那就是说,工作尚在进行中,它的一些功能也许会作为早期的标准扩展或至少作为 beta 登场。

遗憾的是,为一门语言添加功能远比删除功能要简单得多。几乎不可避免地,随着时间的推移,语言不是朝着简单的方向发展,而是越来越复杂,越来越让人困惑。即使是那些单独看起来很好的功能,在彼此叠加后也会出现问题。

令人遗憾,Java 社区没有接受这个教训,尽管这种失败并无特殊性。但总有一些太酷又太让人激动的新语法令语言设计者难以抗拒 —— 即便这样的新语法不能解决任何实际问题。于是对 Java 7 的新语言功能就有了巨大的要求,包括闭包、多继承和操作符重载。

我猜想在这一年结束前,会在 Java 7 beta 中看到闭包,也许还能看到操作符重载(有五成的把握),但不会出现多继承。Java 中有太多东西是基于单个根的继承层次。没有可行的方式改进多继承,使之适应这门语言。

目前有许多语法糖方面的提议,有一些有意义,有一些没有。许多提议都专注于将像 getFoo() 这样的方法替换为像 -> 这样的操作符。

列表

最有可能的是使用数组语法来实现集合访问。例如,不再采用下面这样的代码:

List content = new LinkedList(10);
content.add(0, "Fred");
content.add(1, "Barney");
String name = content.get(0);

而是编写如下代码:

List content = new LinkedList(10);
content[0] = "Fred";
content[1] = "Barney";
String name = content[0];

另一种可能性是:允许为列表使用数组初始化程序语法。例如:

LinkedList content = {"Fred", "Barney", "Wilma", "Betty"}

这两项提议都可以在不改变虚拟机(VM)的前提下由编译器稍显神通即可实现,这是任何修订过的语法的一项重要特征。这两项提议都不能使任何现有的源代码失效或重定义现有的源代码,对于新语法来说,这是一个更为重要的问题。

真 正能够影响开发人员生产力的特性功能应该是用于管理表、树和映射表的内置原语,比如在使用 XML 和 SQL 时遇到的那些。JavaScript 下的 E4X 项目和 Microsoft 的 Cω 和 Linq 项目是实现这一想法的先驱,但可悲的是,Java 平台似乎错过了这个机会。如果有人想要通过编译器来玩一个潜在的救场的游戏,这里是一个不容错过的好地方。

属性

很可以还有一些针对属性访问的语法糖。一个建议是使用 -> 作为调用 getFoo setFoo 的缩写。例如,不再使用如下代码:

Point p = new Point();
p.setX(56);
p.setY(87);
int z = p.getX();

而是使用如下代码:

Point p = new Point();
p->X = 56;
p->Y = 87;
int z = p->X;

也有人建议用另外一些符号来代替 ->,包括 .#

将来,您有可能必须将 Point 类中的相关字段显式地标识为属性,如:

public class Point {

public int property x;
public int property y;

}

我个人对此并未产生什么深刻的印象。我宁愿 Java 平台采纳一项更为激进的方法,让我们可以真正地使用公共字段。然而,如果将 getter 或 setter 定义为与字段相同的名称,然后读写字段就会自动地分派到相应方法中。这样做所使用的语法更少,也更加灵活。

随机精度算法

非操作符重载

值得一提的是,对标准数学符号的重用不同于 操作符重载,至少不是在 C++ 中引起问题的那种重载。加号和其他操作符在任何程序中都具有明确的意义。无论在哪一个程序中,它们的意义都不会有所更改。对于相似的操作重用相同的语法让 代码更易于阅读。若重新定义语法,使之在不同的程序中有不同的意义,代码就会较难理解。

另一项将方法替换为操作符的建议致力于 BigDecimalBigInteger。例如,目前您不得不像这样编写不限精度的算法:

BigInteger low  = BigInteger.ONE;
BigInteger high = BigInteger.ONE;
for (int i = 0; i < 500; i++) {
System.out.print(low);
BigInteger temp = high;
high = high.add(low);
low = temp;
};

写成这样会更清晰:

BigInteger low  = 1;
BigInteger high = 1;
for (int i = 0; i < 500; i++) {
System.out.print(low);
BigInteger temp = high;
high = high + low;
low = temp;
};

这项建议似乎无关紧要,但它可能会导致过度使用这些类,进而导致尚不成熟的代码中性能降低。

将 JAM 从 JAR 中分离出来

Java 7 会抚平 Java 开发人员长久以来积聚的愤怒:各种各样的类加载器和相关的 classpath。Sun 公司在 Java Module System 这个问题上经受了又一次打击。数据将存储到 .jam 文件,而不是 .jar 文件中。这是一种 “superjar”,它包含了所有的代码和元数据。最重要的是,Java Module System 将首次支持版本,所以可以说一个程序需要 Xerces 2.7.1 而不是 2.6。它也允许指定依赖项;例如,可以说一个 JAM 程序需要 JDOM。它也要允许在加载一个模块时不必加载全部模块。最终,它要支持一个集中式的存储库,其中要能提供多个不同的 JAM 的不同版本,应用程序能够从中挑选所需。如果 JMS 适用,jre/lib/ext 将会成为过去时。

包访问

我 也希望 Java 7 能够稍微放松一下访问限制。子包也许能够看到上层包里的包保护字段和类方法。也就是说,子包也许能够看到上层包里明确声明友好性的包保护成员。不论用哪种 方式,将应用程序分割成多个包都会变得简单的多,也会显著地改善可测试性。只要子包中含有单元测试,就不必使用公共方法去进行测试。

文件系统访问

自 从 1995 年开始,文件系统访问就成为 Java 平台的一个主要问题。十多年后,还是没有可信赖的跨平台方式来执行如复制或移动文件这类基本操作。处理这个问题是过去至少三个版本的 JDK(1.4、1.5 和 1.6)的公开问题。遗憾的是,为了迎合不怎么普遍却更具诱惑的操作,如内存映射 I/O,有些乏味但却很必要的 API 被搁到了一边。JSR 203 可能会最终解决这个问题,给我们一个可行的、跨平台文件系统 API。工作组也许会再一次对其无比崇尚的真正的异步输入/输出文件系统这个相对不重要的问题上花费过多时间,从而让该 API 再一次束之高阁。下一年的这个时候我们就会知道。


没有操作符重载和Property的Java是让我们这些习惯C#人非常郁闷的, Java总算将要在下个版本改进这些东西了, 或许到那时我会更多的尝试使用Java和Java平台来做一些事情..


Posted on 2007-02-27 22:20 Adrian H. 阅读(...) 评论(...) 编辑 收藏