购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.2 Java“白皮书”的关键术语

Java的设计者已经编写了颇有影响力的“白皮书”,用来解释设计的初衷以及完成的情况,并且发布了一个简短的摘要。这个摘要用下面11个关键术语进行组织:

1)简单性               7)可移植性

2)面向对象              8)解释型

3)网络技能(Network-Savvy)     9)高性能

4)健壮性              10)多线程

5)安全性              11)动态性

6)体系结构中立

本节将论述下列主要内容:

●给出白皮书中对每个关键术语的概述,这是Java设计者对相关术语的论述。

●凭借Java当前版本的使用经验,给出对这些术语的理解。

注释: 写这本书时,白皮书可以在www.oracle.com/technetwork/java/langenv-140151.html.上找到。对于11个关键术语的论述请参看http://labs.oracle.com/features/tenyeares/volcd/papers/7Gosling.pdf。

1.2.1 简单性

人们希望构建一个无须深奥的专业训练就可以进行编程的系统,并且要符合当今的标准惯例。因此,尽管人们发现C++不太适用,但在设计Java的时候还是尽可能地接近C++,以便系统更易于理解。Java剔除了C++中许多很少使用、难以理解、易混淆的特性。在目前看来,这些特性带来的麻烦远远多于其带来的好处。

的确,Java语法是C++语法的一个“纯净”版本。这里没有头文件、指针运算(甚至指针语法)、结构、联合、操作符重载、虚基类等(请参阅本书各个章节给出的C++注释,那里比较详细地解释了Java与C++之间的区别)。然而,设计者并没有试图清除C++中所有不适当的特性。例如,switch语句的语法在Java中就没有改变。如果知道C++就会发现可以轻而易举地将其转换成Java。

如果已经习惯于使用可视化的编程环境(例如Visual Basic),你就不会觉得Java简单了。Java有许多奇怪的语法(尽管掌握其要领并不需要很长时间),更重要的是,使用Java需要自己编写大量的程序。Visual Basic的魅力在于它的可视化设计环境几乎自动地为应用程序提供了大量的基础结构。而使用Java实现同样的功能却需要手工编制代码,通常代码量还相当大。然而,已经有一些支持“拖放”风格程序开发的第三方开发环境。

简单的另一个方面是小。Java的目标之一是支持开发能够在小型机器上独立运行的软件。基本的解释器以及类支持大约仅为40KB;再加上基础的标准类库和对线程的支持(基本上是一个自包含的微内核)大约需要增加175KB。

在当时,这是一个了不起的成就。当然,由于不断的扩展,类库已经相当庞大了。现在有一个独立的具有较小类库的Java微型版(Java Micro Edition)用于嵌入式设备。

1.2.2 面向对象

简单地讲,面向对象设计是一种程序设计技术。它将重点放在数据(即对象)和对象的接口上。用木匠打一个比方,一个“面向对象的”木匠始终关注的是所制作的椅子,第二位才是所使用的工具;一个“非面向对象的”木匠首先考虑的是所用的工具。在本质上,Java的面向对象能力与C++是一样的。

在过去的40年里,面向对象已经证明了自身的价值,一种现代的程序设计语言不使用面向对象技术简直让人难以置信。的确,Java的面向对象特性与C++旗鼓相当。Java与C++的主要不同点在于多继承,在Java中,取而代之的是简单的接口概念,以及Java的元类(metaclass)模型(有关这部分内容将在第5章中讨论)。

注释: 如果没有使用面向对象程序设计语言的经验,你一定要仔细阅读第4章~第6章。这些章节解释了什么是面向对象程序设计以及在编程实现复杂的项目时为什么比传统的像C或Basic这样的面向过程的语言更加有效。

1.2.3 网络技能

Java有一个扩展的例程库,用于处理像HTTP和FTP之类的TCP/IP协议。Java应用程序能够通过URL打开和访问网络上的对象,其便捷程度就好像访问本地文件一样。

人们已经看到Java的网络能力强大且易于使用。任何曾经试图使用其他语言进行网络编程的人都会惊呼Java竟然把类似打开socket连接这类繁重的任务都变得如此简单(在本书的卷II中介绍网络连接)。另外,远程方法调用机制使得分布式对象之间可以进行通信(也将在卷II中介绍)。

1.2.4 健壮性

Java的设计目标之一在于使得Java编写的程序具有多方面的可靠性。Java投入了大量的精力进行早期的问题检测、后期动态的(运行时)检测,并消除了有出错倾向的状态……Java和C++最大的不同在于Java采用的指针模型可以消除重写内存和损坏数据的可能性。

这个特性非常有用。Java编译器能够检测许多在其他语言中仅在运行时刻才能够检测出来的问题。至于第二点,对于曾经花费几个小时来检查由于指针bug而引起内存冲突的人来说,一定很喜欢Java的这一特性。

如果曾经只使用过Visual Basic这类没有显式指针的语言,你就会感觉这么说似乎有些小题大做了。然而,C程序员就没有这样幸运了。他们需要利用指针存取字符串、数组、对象,甚至文件。在Visual Basic中,根本不必使用指针访问这些实体,也不必关心有关内存分配的问题。另一方面,在没有指针的语言中,许多数据结构很难实现。Java具有双方的优势。它不需要使用指针构造诸如字符串、数组这样的结构。如果必要的话,它也能够具有指针的能力,如链表。Java绝对是安全的,其原因是永远不会存取一个“坏的”指针,造成内存分配的错误,也不必防范内存泄漏。

1.2.5 安全性

Java适用于网络/分布式环境。为了达到这个目标,在安全方面投入了很大精力。使用Java可以构建防病毒、防篡改的系统。

本书的第1版曾经说过:“永远不要把话说绝!”事实证明这是正确的。在Java开发工具箱第1版启用后不久,普林斯顿大学的一些安全专家就发现了在JDK1.0中的某些安全特性方面存在着一些非常隐蔽的bug。Sun Microsystems大力支持对Java的安全性的研究,制定了供人们使用的规范,实现了虚拟机和安全库,并迅速地处理了所有已知的安全bug。在任何情况下,蒙骗Java的安全机制都是十分困难的。现在,发现bug的技术越来越强,数目越来越少。

从一开始,Java就设计成能够防范各种攻击,其中包括:

●运行时堆栈溢出。如,蠕虫等病毒常用的攻击手段。

●在自己的处理空间之外破坏内存。

●未经授权读写文件。

许多安全特性相继不断地加入到Java中。自从Java 1.1问世以来,Java就有了数字签名类(digitally signed class)的概念(请参看卷II)。通过数字签名类,可以确定类的作者。如果信任这个类的作者,这个类就可以在你的机器上拥有更多的权限。

注释: 来自微软的基于ActiveX技术的竞争代码传输机制,其安全性完全依赖于数字签名。这显然是不够的,因为微软自身产品的任何用户都可以证实,来自知名提供商的程序会崩溃并对系统产生危害。Java的安全机制比ActiveX要强得多,因为它是在应用程序运行时加以控制并制止恶意性破坏的。

1.2.6 体系结构中立

编译器生成一个体系结构中立的目标文件格式,这是一种编译过的代码,只要有Java运行时系统,就可以在许多处理器上运行。Java编译器通过生成与特定的计算机体系结构无关的字节码指令来实现这一特性。精心设计的字节码不仅可以很容易地在任何机器上解释执行,而且还可以迅速地翻译成本地机器的代码。

这并不是什么新的思路。40多年以前,Niklaus Wirth实现的原始Pascal以及UCSD Pascal系统都使用了这种技术。

当然,解释字节码肯定会比全速运行机器指令慢很多。所以说,这是不是一个好的思路还很难讲!然而,虚拟机有一个选项,可以将使用最频繁的字节码序列翻译成机器码,这一过程被称为即时编译。这一策略已经证明十分有效,致使微软的.NET平台也依赖于虚拟机。

虚拟机还有一些其他的优点。虚拟机可以检测指令序列的行为,以增强其安全性。有些程序还可以快速地生成字节码,并动态地增强所运行程序的处理能力。

1.2.7 可移植性

与C和C++不同,Java规范中没有“依赖具体实现”的地方。基本数据类型的大小以及有关算法都做了明确的说明。

例如,Java中的int永远为32位的整数,而在C/C++中,int可能是16位整数、32位整数,也可能是编译器提供商指定的其他大小。唯一的限制只是int类型的大小不能低于short int,并且不能高于long int。在Java中,数据类型具有固定的大小,这消除了代码移植时令人头痛的主要问题。二进制数据以固定的格式进行存储和传输,消除了字节顺序的困扰。字符串是用标准的Unicode格式存储的。

作为系统组成部分的类库,定义了可移植的接口。例如,有一个抽象的Window类给出了在UNIX、Windows和Macintosh环境下的不同实现。

凡是尝试过的人都知道,要编写一个在Windows、Macintosh和10种不同风格的UNIX上看起来都不错的程序有多么困难。Java 1.0就尝试着做了这么一个壮举,发布了一个将常用的用户界面元素映射到不同平台上的简单工具箱。遗憾的是,花费了大量的心血,却构建了一个在各个平台上都难以让人接受的库(而且,在不同平台的图形实现中有不同的bug)。不过,这毕竟是个开端。对于许多应用问题来说,可移植性比华而不实的用户界面更加重要;而且这些应用程序从Java的早期版本中获益匪浅。现在,用户界面工具箱已经完全重写了,不再依赖于主机的用户界面。现在的Java版本比早期版本更加稳定,更加吸引人。

1.2.8 解释型

Java解释器可以在任何移植了解释器的机器上执行Java字节码。由于链接是一个增量式且轻量级的过程,所以,开发过程也变得更加快捷,更加具有探索性。

增量式链接有其优势,但给开发过程带来的好处显然是言过其实了。事实上,早期的Java开发工具的速度相当慢。现在,使用即时编译器将字节码翻译成机器码。

1.2.9 高性能

尽管对解释后的字节码性能已经比较满意,但在有些场合下还需要更加高效的性能。字节码可以(在运行时刻)快速地翻译成运行这个应用程序的特定CPU的机器码。

使用Java的头几年,许多用户不同意这样的看法:性能就是“适用性更强”。然而,现在的即时编译器已经非常出色,以至于成了传统编译器的竞争对手。在某些情况下,甚至超越了传统编译器,其原因是它们含有更多的可用信息。例如,即时编译器可以监控经常执行哪些代码并优化这些代码以提高速度。更为复杂的优化是消除函数调用(即“内嵌”)。即时编译器知道哪些类已经加载。如果基于当前加载的类集,且特定的函数不被覆盖的话就可以内嵌。必要时,还可以撤销优化。

1.2.10 多线程

多线程可以带来更好的交互响应和实时行为。

如果曾经使用过其他语言编写多线程的应用程序,就会对Java多线程处理的便捷性惊叹不已。只要操作系统支持,Java中的线程就可以利用多个处理器。在底层,主流平台的线程实现机制各不相同,Java并没有花费太大的力气对此实现平台无关性。在不同的机器上,只是调用多线程的代码完全相同;Java把多线程的实现交给了底层的操作系统或线程库来完成。尽管如此,多线程编译的简单性是Java成为颇具魅力的服务器端开发语言的主要原因之一。

1.2.11 动态性

从各种角度看,Java与C或C++相比更加具有动态性。它能够适应不断发展的环境。库中可以自由地添加新方法和实例变量,而对客户端却没有任何影响。在Java中找出运行时类型信息十分简单。

当需要将某些代码添加到正在运行的程序中时,动态性将是一个非常重要的特性。一个很好的例子是:从Internet上下载代码,然后在浏览器上运行。在Java 1.0中,不能直接获得运行时的类型信息,而Java的当前版本允许程序员知道对象的结构和行为。这对于必须在运行时分析对象的系统来说非常有用。这些系统有:Java GUI构建器、智能调试器、可插拔组件以及对象数据库。

注释: Java成功地推出后不久,微软就发布了一个叫做J++的产品,它与Java有相同的编程语言以及虚拟机。现在,微软不再支持J++,取而代之的是另一种被称为C#的语言。C#与Java有很多相似之处,然而使用的却是完全不同的虚拟机。甚至还有一种J#语言可将J++的应用迁移到使用C#的虚拟机上。本书不准备介绍J++、C#或J#语言。 h4h+jTOVYP41E1xt2t6iV7OazzeThB2FCPeZysaM96FUoAK6hOehW2LxCGHeL7Tv

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开