Java 到底是什么?
对于世界各地的计算机用户来说,Java 会让人联想到各种各样的画面。有些人会想到从网页上挥舞的飞行头部和卡通人物。另一些人则会想起段错误和卡死的 Netscape 浏览器。大多数人只能盯着冒着热气的咖啡图标,不知道这一切到底意味着什么。本文将讨论 Java 到底是什么,以及它在计算大格局中的位置。
Java 编程语言大致类似于 C++、Objective C 和 Smalltalk,删除了一些特性,并添加了一些特性
它是过程式的,像 C 一样,而不是像 Lisp 那样的函数式。
它是面向对象的,像 C++ 一样。它支持类、单类继承、多接口继承、访问保护和异常。它不支持运算符重载或模板(尽管它未来可能会支持类似模板的结构)。
所有类型转换都是动态且安全的;不可能将对象转换为不适当的类型。
Java 中的一切都是面向类的。没有全局作用域,没有全局变量,也没有显式的函数指针。
支持任意维度的数组,并且像对象一样运作。
它支持线程,并提供同步原语。线程,有时称为轻量级进程,允许几个独立的执行路径同时运行在一个程序中。同步原语确保单独的任务以正确的顺序执行。
它支持模块,因此不需要预处理器。没有 #include 指令,因为等效的功能已内置于语言中),没有宏,没有 #define 等。
它支持垃圾回收,并且不支持显式释放。这极大地简化了编程,并消除了所有内存分配错误。
所有对象都隐式地使用引用语义,这大致意味着每个对象都像一个指针,但使用时就好像它是一个值。所有基本类型(int、char 等)都使用值语义。
Java 是安全的,这意味着不可能:解引用段外的指针;使用已释放的内存;或将对象用作错误的类型。Java 程序永远不会导致段错误(实际上,Java 解释器确实有一些可能导致应用程序崩溃的错误,但这些错误正在被修复)。
Java 捆绑了一个名为 Java API(应用程序接口)的标准库,它提供
基本的文件输入和输出
网络,特别是 TCP/IP、UDP 和 HTTP
基本的动态容器类,如 Vector、Dictionary 等。
图形和 GUI 编程
Java 系统的另一个重要组成部分是编译器。Java 编译器将源文件(例如,Foo.java)翻译成一个或多个类文件(例如,Foo.class)。.class 文件大致对应于 C 中的 .o(或 .obj)文件,但有一个关键的区别:虽然 .o 文件包含机器特定的指令,但 .class 文件仅包含一种通用的伪汇编代码,称为字节码,它在所有平台中都是统一的。为了实现这一点,每个支持 Java 的平台都必须有一个 Java 运行时,它将解释和执行 Java 字节码。
Java 编译成的底层字节码在 Sun 的 Java 虚拟机(或 JVM)规范 (java.sun.com/doc/vmspec/html/vmspec-1.html) 中描述。Java 运行时模拟 JVM,以便它可以运行 .class 文件中包含的 Java 字节码。JVM 是 Java 普遍性的关键组成部分;与其要求每个单独的应用程序都支持多个平台,开发人员只需要编写一个版本的程序,并确保它可以在任何地方运行。唯一需要跨多个平台移植的程序是 Java 运行时。尽管 Java 还很年轻,但大多数主要平台都已支持。
现在让我们花一点时间来追溯让你在网页浏览器中看到挥舞的动画人物所涉及的步骤。
网络上的程序员编写一个 Java 程序,并使用 Java 编译器将 .java 源文件转换为 .class 文件。这位程序员将对这些 .class 文件的引用放在她的网页中的 <APPLET> 标签内。
你将浏览器指向她的网页,你的浏览器看到了指向 .class 文件的 <APPLET> 标签。然后,你的浏览器通过网络下载她的 .class 文件。
你的浏览器启动其 Java 运行时子系统,并开始执行它下载的 .class 文件。
此时,你可能会想,当令人安慰的卡通人物分散你对硬盘重新格式化的声音的注意力时,是什么阻止了恶意程序员对你的计算机做可怕的事情。答案在于 Java SecurityManager。这个类是标准的一部分,为所有不受信任的程序实现了一个安全策略。在这里,不受信任的程序是指那些通过网络下载的程序。在当前版本的 Netscape 中,Java 运行时使用的 SecurityManager 不允许不受信任的 Java 程序读取或写入文件,也不允许它们建立网络连接到程序来源主机之外的任何地方。因此,这形成了一种沙箱,Java 程序被限制在其中。
Java 安全模型的另一个关键方面是字节码验证器。字节码验证器检查所有传入的程序,以确保它们满足一些基本的安全约束(例如,每个指针类型转换都是安全的,不会发生堆栈溢出等)。这防止了恶意程序员通过手工编写 Java 字节码来创建不良的 .class 文件,以试图规避 Java 语言的安全特性。如果你的 Netscape 下载的 .class 文件未能通过验证阶段,它将简单地拒绝运行该代码。
大多数人将 Java 视为 Web 的编程语言。虽然 Java 在这方面确实表现出色,但它实际上更通用;它也适用于独立的、非 Web 编程。你可以编写可以在 Web 浏览器之外运行的 Java 程序,并且作为受信任的程序,它们可以执行 C 或 C++ 程序可能执行的所有操作,例如访问文件系统。事实上,在 Linux 2.0 内核之前的开发版本中,有对 Java 二进制格式的支持。这种支持意味着你可以像运行 ELF 或 a.out 格式的可执行文件一样,从命令行运行 Java 字节码程序,而无需显式调用 Java 运行时。用 Java 编写程序的最大优点是它们可以立即在各种平台和架构之间移植。
当前 Java 实现的一个问题是速度;在大多数当前的实现中,性能比 C 慢很多倍。这是因为 Java 字节码是被解释执行的,这与从 C 程序编译的本地汇编代码不同,后者是由处理器直接运行的。然而,通过开发所谓的“即时”编译器,速度问题正在得到缓解。这些编译器(实际上是 Java 运行时系统的一部分)动态地将 .class 文件编译成本地汇编代码。通过这样做,它们可以将 Java 程序的运行速度提高许多倍。此外,由于它们仅在执行时编译类,因此消除了与传统编译相关的典型初始延迟。随着这些编译器的成熟,我们可以预期与 Java 相关的性能损失将会消失。
此时,你可能想知道如何才能启用 Java。如果你只是想在你的机器上运行 Java 小程序(即通过 Web 传输的 Java 程序),你可以使用最新的 Netscape 测试版来做到这一点,该版本可从 www.netscape.com/ 获取。如果你想开始尝试 Java 编程,或运行非浏览器独立的 Java 程序,你可以使用免费的 Linux 移植版 Java 开发工具包 (JDK) 来做到这一点。将你的浏览器指向 java.blackdown.org/java-linux/Information.html 以了解在哪里获取它。如果你想要 JDK 中包含的 Java 编译器的替代方案,那么可以使用 EspressoGrinder,它是 JDK 编译器的直接替换。EspressoGrinder 是用 Java 编写的,因此可以在任何已移植 Java 运行时的环境中运行。你可以从 wwwipd.ira.uka.de/~espresso/ 获取它。如果你想了解更多关于 Java、JDK 和一般 Java 事件的信息,请查看 Sun 的网站:www.javasoft.com/java.sun.com/devcorner.html。Java 常见问题解答可从 sunsite.unc.edu/javafaq/javafaq.html 获取。
Java 的政治和经济意义是巨大的,尤其是对于 Linux 开发者而言。由于 JVM 中高度的虚拟化,开发者可以自由地在非目标平台上创建他们的应用程序。因此,现在可以使用你的 Linux 系统来开发 Java 应用程序,这些应用程序可以轻松地利用 Windows、Macintosh、HP-UX 或 SGI 机器(仅举几例)的普及度。此外,Linux 无疑也将能够从其他平台下编写的应用程序中获益,原因完全相同。总的来说,我们可以预期 Java 将迎来软件互操作性的新时代,赋能所有平台上的开发者和用户。
Rudi Cilibrasi (cilibrar@ugcs.caltech.edu) 拥有超过十年的计算机编程经验;他作为一名软件顾问工作,专注于 Java、C++ 和 Linux。