友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
Java编程思想第4版[中文版](PDF格式)-第18部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
+ rt。totalMemory()
+ 〃 Free Memory = 〃
+ rt。freeMemory());
其中,totalMemory()和freeMemory ()返回的是数值,并非String 对象。如果将一个数值“加”到一个字串
身上,会发生什么情况呢?同我们一样,编译器也会意识到这个问题,并魔术般地调用一个方法,将那个数
值(int,float 等等)转换成字串。经这样处理后,它们当然能利用加号“加”到一起。这种“自动类型转
换”亦划入“运算符过载”处理的范畴。
许多Java 著作都在热烈地辩论“运算符过载”(C++的一项特性)是否有用。目前就是反对它的一个好例
子!然而,这最多只能算编译器(程序)的问题,而且只是对 String 对象而言。对于自己编写的任何源代
码,都不可能使运算符“过载”。
通过为 Runtime 类调用 getRuntime()方法,main()的第五行创建了一个Runtime 对象。返回的则是指向一个
Runtime 对象的句柄。而且,我们不必关心它是一个静态对象,还是由 new 命令创建的一个对象。这是由于
我们不必为清除工作负责,可以大模大样地使用对象。正如显示的那样,Runtime 可告诉我们与内存使用有
关的信息。
2。8 注释和嵌入文档
Java 里有两种类型的注释。第一种是传统的、C 语言风格的注释,是从 C++继承而来的。这些注释用一个
“/*”起头,随后是注释内容,并可跨越多行,最后用一个“*/”结束。注意许多程序员在连续注释内容的
每一行都用一个“*”开头,所以经常能看到象下面这样的内容:
/* 这是
* 一段注释,
* 它跨越了多个行
*/
但请记住,进行编译时,/*和*/之间的所有东西都会被忽略,所以上述注释与下面这段注释并没有什么不
同:
/* 这是一段注释,
它跨越了多个行 */
第二种类型的注释也起源于C++。这种注释叫作“单行注释”,以一个“//”起头,表示这一行的所有内容
都是注释。这种类型的注释更常用,因为它书写时更方便。没有必要在键盘上寻找“/”,再寻找“*”(只
需按同样的键两次),而且不必在注释结尾时加一个结束标记。下面便是这类注释的一个例子:
// 这是一条单行注释
55
…………………………………………………………Page 57……………………………………………………………
2。8。1 注释文档
对于Java 语言,最体贴的一项设计就是它并没有打算让人们为了写程序而写程序——人们也需要考虑程序的
文档化问题。对于程序的文档化,最大的问题莫过于对文档的维护。若文档与代码分离,那么每次改变代码
后都要改变文档,这无疑会变成相当麻烦的一件事情。解决的方法看起来似乎很简单:将代码同文档“链
接”起来。为达到这个目的,最简单的方法是将所有内容都置于同一个文件。然而,为使一切都整齐划一,
还必须使用一种特殊的注释语法,以便标记出特殊的文档;另外还需要一个工具,用于提取这些注释,并按
有价值的形式将其展现出来。这些都是Java 必须做到的。
用于提取注释的工具叫作javadoc。它采用了部分来自Java 编译器的技术,查找我们置入程序的特殊注释标
记。它不仅提取由这些标记指示的信息,也将毗邻注释的类名或方法名提取出来。这样一来,我们就可用最
轻的工作量,生成十分专业的程序文档。
javadoc输出的是一个 HTML 文件,可用自己的Web 浏览器查看。该工具允许我们创建和管理单个源文件,并
生动生成有用的文档。由于有了jvadoc,所以我们能够用标准的方法创建文档。而且由于它非常方便,所以
我们能轻松获得所有Java 库的文档。
2。8。2 具体语法
所有 javadoc命令都只能出现于“/**”注释中。但和平常一样,注释结束于一个“*/”。主要通过两种方式
来使用 javadoc:嵌入的HTML ,或使用“文档标记”。其中,“文档标记”(Doc tags)是一些以“@”开头
的命令,置于注释行的起始处(但前导的“*”会被忽略)。
有三种类型的注释文档,它们对应于位于注释后面的元素:类、变量或者方法。也就是说,一个类注释正好
位于一个类定义之前;变量注释正好位于变量定义之前;而一个方法定义正好位于一个方法定义的前面。如
下面这个简单的例子所示:
/** 一个类注释 */
public class docTest {
/** 一个变量注释 */
public int i;
/** 一个方法注释 */
public void f() {}
}
注意 javadoc 只能为 public (公共)和protected (受保护)成员处理注释文档。“private”(私有)和
“友好”(详见5 章)成员的注释会被忽略,我们看不到任何输出(也可以用…private 标记包括private 成
员)。这样做是有道理的,因为只有public 和protected 成员才可在文件之外使用,这是客户程序员的希
望。然而,所有类注释都会包含到输出结果里。
上述代码的输出是一个 HTML 文件,它与其他Java 文档具有相同的标准格式。因此,用户会非常熟悉这种格
式,可在您设计的类中方便地“漫游”。设计程序时,请务必考虑输入上述代码,用 javadoc处理一下,观
看最终HTML 文件的效果如何。
2。8。3 嵌入 HTML
javadoc将 HTML 命令传递给最终生成的 HTML 文档。这便使我们能够充分利用HTML 的巨大威力。当然,我们
的最终动机是格式化代码,不是为了哗众取宠。下面列出一个例子:
/**
*
* System。out。println(new Date());
*
*/
亦可象在其他Web 文档里那样运用 HTML ,对普通文本进行格式化,使其更具条理、更加美观:
/**
56
…………………………………………………………Page 58……………………………………………………………
* 您甚至可以插入一个列表:
*
* 项目一
* 项目二
* 项目三
*
*/
注意在文档注释中,位于一行最开头的星号会被javadoc 丢弃。同时丢弃的还有前导空格。javadoc 会对所
有内容进行格式化,使其与标准的文档外观相符。不要将或这样的标题当作嵌入 HTML 使用,因为
javadoc会插入自己的标题,我们给出的标题会与之冲撞。
所有类型的注释文档——类、变量和方法——都支持嵌入 HTML 。
2。8。4 @see :引用其他类
所有三种类型的注释文档都可包含@see 标记,它允许我们引用其他类里的文档。对于这个标记,javadoc会
生成相应的 HTML ,将其直接链接到其他文档。格式如下:
@see 类名
@see 完整类名
@see 完整类名#方法名
每一格式都会在生成的文档里自动加入一个超链接的“See Also ”(参见)条目。注意 javadoc不会检查我
们指定的超链接,不会验证它们是否有效。
2。8。5 类文档标记
随同嵌入HTML 和@see 引用,类文档还可以包括用于版本信息以及作者姓名的标记。类文档亦可用于“接
口”目的(本书后面会详细解释)。
1。 @version
格式如下:
@version 版本信息
其中,“版本信息”代表任何适合作为版本说明的资料。若在 javadoc命令行使用了 “…version”标记,就
会从生成的 HTML 文档里提取出版本信息。
2。 @author
格式如下:
@author 作者信息
其中,“作者信息”包括您的姓名、电子函件地址或者其他任何适宜的资料。若在javadoc命令行使用了“
author”标记,就会专门从生成的HTML 文档里提取出作者信息。
可为一系列作者使用多个这样的标记,但它们必须连续放置。全部作者信息会一起存入最终 HTML 代码的单独
一个段落里。
2。8。6 变量文档标记
变量文档只能包括嵌入的HTML 以及@see 引用。
2。8。7 方法文档标记
除嵌入HTML 和@see 引用之外,方法还允许使用针对参数、返回值以及违例的文档标记。
1。 @param
格式如下:
57
…………………………………………………………Page 59……………………………………………………………
@param 参数名 说明
其中,“参数名”是指参数列表内的标识符,而“说明”代表一些可延续到后续行内的说明文字。一旦遇到
一个新文档标记,就认为前一个说明结束。可使用任意数量的说明,每个参数一个。
2。 @return
格式如下:
@return 说明
其中,“说明”是指返回值的含义。它可延续到后面的行内。
3。 @exception
有关“违例”(Exception)的详细情况,我们会在第 9 章讲述。简言之,它们是一些特殊的对象,若某个方
法失败,就可将它们“扔出”对象。调用一个方法时,尽管只有一个违例对象出现,但一些特殊的方法也许
能产生任意数量的、不同类型的违例。所有这些违例都需要说明。所以,违例标记的格式如下:
@exception 完整类名 说明
其中,“完整类名”明确指定了一个违例类的名字,它是在其他某个地方定义好的。而“说明”(同样可以
延续到下面的行)告诉我们为什么这种特殊类型的违例会在方法调用中出现。
4。 @deprecated
这是Java 1。1 的新特性。该标记用于指出一些旧功能已由改进过的新功能取代。该标记的作用是建议用户不
必再使用一种特定的功能,因为未来改版时可能摒弃这一功能。若将一个方法标记为@deprecated,则使用该
方法时会收到编译器的警告。
2。8。8 文档示例
下面还是我们的第一个 Java 程序,只不过已加入了完整的文档注释:
//: Property。java
import java。util。*;
/** The first Thinking in Java example program。
* Lists system information on current machine。
* @author Bruce Eckel
* @author http://BruceEckel。
* @version 1。0
*/
public class Property {
/** Sole entry point to class & application
* @param args array of string arguments
* @return No return value
* @exception exceptions No exceptions thrown
*/
public static void main(String'' args) {
System。out。println(new Date());
Properties p = System。getProperties();
p。list(System。out);
System。out。println(〃……Memory Usage:〃);
Runtime rt = Runtime。getRuntime();
System。out。println(〃Total Memory = 〃
+ rt。totalMemory()
+ 〃 Free Memory = 〃
+ rt。freeMemory());
}
58
…………………………………………………………Page 60……………………………………………………………
} ///:~
第一行:
//: Property。java
采用了我自己的方法:将一个“:”作为特殊的记号,指出这是包含了源文件名字的一个注释行。最后一行也
用这样的一条注释结尾,它标志着源代码清单的结束。这样一来,可将代码从本书的正文中方便地提取出
来,并用一个编译器检查。这方面的细节在第 17章讲述。
2。9 编码样式
一个非正式的Java 编程标准是大写一个类名的首字母。若类名由几个单词构成,那么把它们紧靠到一起(也
就是说,不要用下划线来分隔名字)。此外,每个嵌入单词的首字母都采用大写形式。例如:
class AllTheColorsOfTheRainbow { // 。。。}
对于其他几乎所有内容:方法、字段(成员变量)以及对象句柄名称,可接受的样式与类样式差不多,只是
标识符的第一个字母采用小写。例如:
class AllTheColorsOfTheRainbow {
int anIntegerRepresentingColors;
void changeTheHueOfTheColor(int newHue) {
// 。。。
}
// 。。。
}
当然,要注意用户也必须键入所有这些长名字,而且不能输错。
2。10 总结
通过本章的学习,大家已接触了足够多的 Java 编程知识,已知道如何自行编写一个简单的程序。此外,对语
言的总体情况以及一些基本思想也有了一定程度的认识。然而,本章所有例子的模式都是单线形式的“这样
做,再那样做,然后再做另一些事情”。如果想让程序作出一项选择,又该如何设计呢?例如,“假如这样
做的结果是红色,就那样做;如果不是,就做另一些事情”。对于这种基本的编程方法,下一章会详细说明
在Java 里是如何实现的。
2。11 练习
(1) 参照本章的第一个例子,创建一个“Hello,World”程序,在屏幕上简单地显示这句话。注意在自己的
类里只需一个方法(“main ”方法会在程序启动时执行)。记住要把它设为static 形式,并置入自变量列
表——即使根本不会用到这个列表。用javac 编译这个程序,再用java 运行它。
(2) 写一个程序,打印出从命令行获取的三个自变量。
(3) 找出Property。java 第二个版本的代码,这是一个简单的注释文档示例。请对文件执行javadoc,并在
自己的Web 浏览器里观看结果。
(4) 以练习(1)的程序为基础,向其中加入注释文档。利用javadoc,将这个注释文档提取为一个HTML 文
件,并用Web 浏览器观看。
59
…………………………………………………………Page 61……………………………………………………………
第 3 章 控制程序流程
“就象任何有感知的生物一样,程序必须能操纵自己的世界,在执行过程中作出判断与选择。”
在Java 里,我们利用运算符操纵对象和数据,并用执行控制语句作出选择。Java 是建立在C++基础上的,所
以对C 和C++程序员来说,对Java 这方面的大多数语句和运算符都应是非常熟悉的。当然,Java 也进行了自
己的一些改进与简化工作。
3。1 使用 Java 运算符
运算符以一个或多个自变量为基础,可生成一个新值。自变量采用与原始方法调用不同的一种形式,但效果
是相同的。根据以前写程序的经验,运算符的常规概念应该不难理解。
加号(+)、减号和负号(…)、乘号(*)、除号(/)以及等号(=)的用法与其他所有编程语言都是类似
的。
所有运算符都能根据自己的运算对象生成一个值。除此以外,一个运算符可改变运算对象的值,这叫作“副
作用”(Side Effect)。运算符最常见的用途就是修改自己的运算对象,从而产生副作用。但要注意生成的
值亦可由没有副作用的运算符生成。
几乎所有运算符都只能操作“主类型”(Primitives)。唯一的例外是“=”、“==”和“!=”,它们能操作
所有对象(也是对象易令人混淆的一个地方)。除此以外,String 类支持“+”和“+=”。
3。1。1 优先级
运算符的优先级决定了存在多个运算符时一个表达式各部分的计算顺序。Java 对计算顺序作出了特别的规
定。其中,最简单的规则就是乘法和除法在加法和减法之前完成。程序员经常都会忘记其他优先级规则,所
以应该用括号明确规定计算顺序。例如:
A = X + Y 2/2 + Z;
为上述表达式加上括号后,就有了一个不同的含义。
A = X + (Y 2)/(2 + Z);
3。1。2 赋值
赋值是用等号运算符(=)进行的。它的意思是“取得右边的值,把它复制到左边”。右边的值可以是任何常
数、变量或者表达式,只要能产生一个值就行。但左边的值必须是一个明确的、已命名的变量。也就是说,
它必须有一个物理性的空间来保存右边的值。举个例子来说,可将一个常数赋给一个变量(A=4; ),但不可
将任何东西赋给一个常数(比如不能4=A)。
对主数据类型的赋值是非常直接的。由于主类型容纳了实际的值,而且并非指向一个对象的句柄,所以在为
其赋值的时候,可将来自一个地方的内容复制到另一个地方。例如,假设为主类型使用“A=B”,那么B 处的
内容就复制到A 。若接着又修改了A,那么B 根本不会受这种修改的影响。作为一名程序员,这应成为自己的
常识。
但在为对象“赋值”的时候,情况却发生了变化。对一个对象进行操作时,我们真正操作的是它的句柄。所
以倘若“从一个对象到另一个对象”赋值,实际就是将句柄从一个地方复制到另一个地方。这意味着假若为
对象使用“C=D”,那么C 和 D 最终都会指向最初只有 D 才指向的那个对象。下面这个例子将向大家阐示这一
点。
这里有一些题外话。在后面,大家在代码示例里看到的第一个语句将是“package 03”使用的“package”语
句,它代表本书第 3 章。本书每一章的第一个代码清单都会包含象这样的一个“package”(封装、打包、包
裹)语句,它的作用是为那一章剩余的代码建立章节编号。在第17 章,大家会看到第 3 章的所有代码清单
(除那些有不同封装名称的以外)都会自动置入一个名为c03 的子目录里;第4 章的代码置入c04;以此类
推。所有这些都是通过第 17 章展示的CodePackage。java 程序实现的;“封装”的基本概念会在第 5 章进行
详尽的解释。就目前来说,大家只需记住象“package 03”这样的形式只是用于为某一章的代码清单建立相
应的子目录。
为运行程序,必须保证在classpath 里包含了我们安装本书源码文件的根目录(那个目录里包含了 c02,
c03c,c04 等等子 目录)。
60
…………………………………………………………Page 62……………………………………………………………
对于Java 后续的版本(1。1。4 和更高版本),如果您的 main()用 package 语句封装到一个文件里,那么必须
在程序名前面指定完整的包裹名称,否则不能运行程序。在这种情况下,命令行是:
java c03。Assignment
运行位于一个“包裹”里的程序时,随时都要注意这方面的问题。
下面是例子:
//: Assignment。java
// Assignment with objects is a bit tricky
package c03;
class Number {
int i;
}
public class Assignment {
public static void main(String'' args) {
Number n1 = new Number();
Number n2 = new Number();
n1。i = 9;
n2。i = 47;
System。out。println(〃1: n1。i: 〃 + n1。i +
〃; n2。i: 〃 + n2。i);
n1 = n2;
System。out。println(〃2: n1。i: 〃 + n1。i +
〃; n2。i: 〃 + n2。i);
n1。i = 27;
System。out。println(〃3: n1。i: 〃 + n1。i +
〃; n2。i: 〃 +
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!