描述
开 本: 128开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787302461999丛书名: 计算机系列教材
本书内容全面,重点突出,通俗易懂、循序渐进、深入浅出,全书共分17章,主要内容包括Java概述、语言基础、选择控制、循环控制、方法、数组、对象和类、继承和多态、抽象类和接口、Java异常处理、常用类和接口、图形用户界面、文件输入输出、多线程编程、数据库编程、网络程序设计、JSP应用技术等。
本书每章都给出了较多的例题与应用实例,各章后有适量的习题以便于读者学习与巩固所学知识。
本书可作为高等院校理工科各专业“Java语言程序设计”类课程的教材,也可供参加自学考试人员、应用系统开发设计人员及其他对程序设计感兴趣的读者参阅。
基础篇
第1章 Java概述 /3
1.1 程序设计语言简介 /3
1.2
Java语言发展简史 /5
1.3
Java语言的特点及版本 /6
1.4 初识简单的Java程序 /10
1.5
Java程序语法概述 /17
1.5.1
Java程序的结构特点 /17
1.5.2
Java程序的书写规则 /17
1.5.3
Java语言字符集与词汇 /18
1.6
JVM、JRE、JDK、API和IDE /21
1.7
Java开发环境 /22
1.7.1
如何运行Java程序 /22
1.7.2
下载JDK /23
1.7.3
JDK的具体安装过程 /24
1.7.4
配置系统环境变量 /26
1.7.5
测试JDK是否安装成功 /27
1.7.6
编译命令和执行命令的用法 /28
1.7.7
集成开发环境 /29
1.8 上机实践要求 /31
1.9 本章小结 /32
1.10
习题 /32
第2章 语言基础 /35
2.1
Java数据类型 /35
2.1.1
基本数据类型 /35
2.1.2
引用类型 /40
2.1.3
数据类型转化 /40
2.2 常量和变量 /42
2.2.1
常量 /42
2.2.2
变量 /43
2.2.3
变量作用域 /46
2.3 运算符和表达式 /47
2.3.1
赋值运算符与赋值表达式 /48
2.3.2
算术运算符与算术表达式 /48
2.3.3
关系运算符 /49
2.3.4
逻辑运算符 /50
2.3.5
位运算符 /50
2.3.6
移位运算符 /51
2.3.7
条件运算符 /52
2.3.8
复合赋值运算符 /53
2.3.9
instanceof运算符 /54
2.3.10
Java运算符优先级 /54
2.3.11
表达式计算举例 /55
2.4 对话框输入输出 /56
2.4.1
String类型 /56
2.4.2
将字符串转换为数值 /57
2.4.3
使用对话框输入输出 /57
2.5 本章小结 /58
2.6 习题 /58
第3章 选择 /61
3.1 布尔(逻辑)表达式 /61
3.1.1
关系表达式 /62
3.1.2
逻辑表达式 /63
3.2
if语句 /65
3.2.1
不带else的if语句 /65
3.2.2
带有else的if语句 /65
3.2.3
if…else if…else语句 /66
3.2.4
if语句的嵌套 /67
3.3
switch 语句 /69
3.4 条件表达式 /70
3.5 格式化控制台输出 /71
3.6 本章小结 /72
3.7 习题 /72
第4章 循环 /75
4.1 循环语句 /76
4.1.1
while循环语句 /76
4.1.2
do…while循环语句 /77
4.1.3
for循环语句 /78
4.1.4
增强for循环语句 /79
4.2 循环的比较及其嵌套 /80
4.3 跳转语句 /81
4.3.1
break关键字 /81
4.3.2
continue关键字 /82
4.4 应用实例 /83
4.5 本章小结 /91
4.6 习题 /92
第5章 方法 /96
5.1 方法定义 /97
5.2 方法调用 /98
5.2.1
有返回值方法 /99
5.2.2
无返回值方法 /99
5.2.3
嵌套调用 /100
5.2.4
递归调用 /101
5.3 方法参数传递 /102
5.3.1
基本数据类型参数传递 /102
5.3.2
引用数据类型参数传递 /103
5.4 方法重载 /104
5.5 变量作用域 /105
5.6 命令行参数 /105
5.7 构造方法 /106
5.7.1
构造方法的定义与作用 /106
5.7.2
构造方法的重载 /108
5.8 可变参数 /109
5.9 垃圾回收机制 /110
5.9.1
finalize()方法 /110
5.9.2
System.gc的作用 /111
5.10
模块化程序设计 /112
5.11
应用实例 /113
5.12
本章小结 /121
5.13
习题 /121
第6章 数组 /125
6.1 一维数组 /126
6.1.1
一维数组声明 /126
6.1.2
一维数组初始化 /126
6.1.3
一维数组的引用 /127
6.1.4
一维数组的处理 /128
6.2 二维及多维数组 /129
6.2.1
二维数组声明 /129
6.2.2
二维数组初始化 /129
6.2.3
二维数组的引用与处理 /130
6.2.4
多维数组 /131
6.3 数组为方法参数 /132
6.3.1
数组作为方法参数 /132
6.3.2
数组为方法返回值 /134
6.4
Arrays类 /134
6.5 应用实例 /134
6.6 本章小结 /141
6.7 习题 /142
核心篇
第7章 对象和类 /147
7.1 面向对象程序设计概述 /147
7.1.1
面向过程的程序设计 /147
7.1.2
面向对象的程序设计 /148
7.1.3
面向对象方法的特征 /148
7.2 类与对象 /151
7.2.1
类的声明 /151
7.2.2
类的实例对象及使用 /153
7.3
this引用句柄 /155
7.4
Java 修饰符 /157
7.4.1
访问控制修饰符 /157
7.4.2
非访问控制修饰符 /160
7.5
Java源文件 /166
7.5.1
源文件声明规则 /166
7.5.2
import语句 /167
7.5.3
一个简单的例子 /167
7.6 本章小结 /168
7.7 习题 /169
第8章 继承和多态 /173
8.1 继承和多态性的概念 /173
8.1.1
继承的概述 /173
8.1.2
多态性的概述 /174
8.2 继承机制 /175
8.2.1
继承的定义 /175
8.2.2
继承的传递性 /178
8.2.3
类中属性的继承与隐藏 /179
8.2.4
方法的继承 /180
8.2.5
方法的覆盖 /181
8.2.6
方法的重载 /183
8.2.7
super引用句柄 /185
8.2.8
implements继承接口 /187
8.2.9
HAS-A 关系 /188
8.3 多态性 /189
8.3.1
多态性的体现 /189
8.3.2
静态多态性 /190
8.3.3
动态多态性 /190
8.3.4
this和super指代使用和转化 /191
8.3.5
虚方法及其举例 /192
8.4 本章小结 /195
8.5 习题 /195
第9章 抽象类和接口 /202
9.1 抽象类 /202
9.1.1
抽象类的定义 /203
9.1.2
抽象类的使用 /204
9.1.3
抽象方法 /207
9.1.4
Java封装 /208
9.2 接口 /209
9.2.1
Java中的接口 /209
9.2.2
接口的继承 /212
9.2.3
接口的多重继承 /213
9.2.4
标记接口 /213
9.3
Java包 /214
9.3.1
Java中的包 /214
9.3.2
创建包 /217
9.3.3
import关键字 /218
9.3.4
package的目录结构 /219
9.3.5
设置CLASSPATH /220
9.4 内部类 /221
9.5 匿名类 /222
9.6 本章小结 /223
9.7 习题 /223
第10章 异常处理 /228
10.1
异常的概念 /228
10.2
异常处理 /230
10.3
自定义异常 /232
10.4
本章小结 /233
10.5
习题 /234
应用篇
第11章 常用类和接口 /239
11.1
字符串处理类 /239
11.1.1
String类 /239
11.1.2
StringBuffer类 /244
11.2
时间日期类 /245
11.2.1
Date类 /246
11.2.2
Calendar类 /246
11.2.3
DateFormat类 /247
11.2.4
SimpleDateFormat类 /247
11.3
Math类 /247
11.4
随机数类Random /248
11.5
Java 数据结构 /249
11.5.1
枚举 /249
11.5.2
向量 /250
11.5.3
栈 /251
11.5.4
哈希表 /252
11.6
集合框架 /252
11.6.1
Collection接口及操作 /255
11.6.2
Set接口及其实现类 /255
11.6.3
对象排序 /257
11.6.4
List接口及其实现类 /257
11.6.5
Map接口及其实现类 /259
11.6.6
集合的输出 /260
11.6.7
集合的工具类Collections /262
11.7
泛型 /263
11.7.1
泛型类 /263
11.7.2
泛型方法 /264
11.8
本章小结 /266
11.9
习题 /266
第12章 图形用户界面 /267
12.1
引言 /267
12.2
AWT与swing /267
12.3
Java GUI API分类 /268
12.3.1
容器类 /268
12.3.2
组件类 /269
12.3.3
辅助类 /270
12.4
容器类与容器布局管理 /270
12.4.1
顶层容器 /270
12.4.2
中间容器 /272
12.4.3
布局管理器 /273
12.5
辅助类 /277
12.5.1
Color类 /278
12.5.2
Font类 /278
12.6
事件处理 /279
12.6.1
事件处理模型 /280
12.6.2
事件及监听者 /283
12.6.3
窗口事件 /289
12.6.4
监听器接口适配器 /290
12.6.5
键盘事件 /291
12.6.6
鼠标事件 /292
12.6.7
Timer类的动画 /293
12.7
常用swing组件 /294
12.8
菜单设计 /295
12.8.1
下拉式菜单 /296
12.8.2
弹出式菜单 /298
12.9
本章小结 /298
12.10
习题 /298
第13章 文件输入输出 /300
13.1
引言 /300
13.1.1
Java流类的层次结构 /301
13.1.2
流类的基本用法 /302
13.2
文件类File /302
13.2.1
文件和目录的概念 /302
13.2.2
文件File类 /303
13.3
文本文件输入输出 /305
13.3.1
使用PrintWriter写数据 /306
13.3.2
使用Scanner读数据 /307
13.4
二进制文件输入输出 /309
13.4.1
二进制I/O类 /310
13.4.2
FileInputStream和FileOutputStream
/310
13.4.3
FilterInputStream和FilterOutputStream /311
13.4.4
DataInputStream和DataOutputStream /311
13.4.5
BufferedInputStream和
BufferedOutputStream /312
13.4.6
ObjectInputStream和
ObjectOutputStream /312
13.5
随机文件访问 /317
13.6
本章小结 /318
13.7
习题 /318
第14章 多线程编程 /320
14.1
多线程概述 /320
14.1.1
线程的基本概念 /320
14.1.2
线程的运行机制 /320
14.2
线程的创建和启动 /321
14.2.1
线程的创建 /321
14.2.2
线程的启动 /323
14.3
线程状态和转换 /324
14.4
线程控制 /325
14.4.1
线程睡眠 /325
14.4.2
线程让步 /325
14.4.3
线程间协作 /326
14.4.4
后台线程 /326
14.4.5
线程优先级 /327
14.5
线程同步处理 /327
14.5.1
多线程引发的问题 /327
14.5.2
同步代码块 /328
14.5.3
同步方法 /328
14.5.4
线程间通信 /329
14.5.5
死锁 /330
14.6
Thread 方法 /330
14.7
本章小结 /332
14.8
习题 /332
第15章 数据库编程 /333
15.1
关系数据库与SQL语言 /333
15.1.1
关系数据库的基本概念 /333
15.1.2
数据定义语言 /333
15.1.3
数据操纵语言 /334
15.1.4
数据查询语言 /335
15.2
Java数据库编程简介 /335
15.3
通过JDBC访问数据库 /335
15.3.1
JDBC访问数据库基本流程 /335
15.3.2
加载数据库驱动程序 /336
15.3.3
创建与数据源的连接 /337
15.3.4
操作数据库 /338
15.3.5
处理操作结果 /340
15.3.6
关闭操作 /341
15.4
JDBC编程实例 /342
15.4.1
创建数据库连接 /342
15.4.2
创建数据表 /343
15.4.3
向表中添加数据 /343
15.4.4
修改数据 /344
15.4.5
删除数据 /345
15.4.6
查询数据信息 /346
15.5
JDBC事务 /346
15.6
本章小结 /349
15.7
习题 /349
第16章 网络程序设计 /350
16.1
网络通信基础 /350
16.1.1
网络通信的基本概念 /350
16.1.2
TCP协议和UDP协议 /351
16.1.3
网络程序设计技术 /352
16.2
URL程序设计 /352
16.2.1
URL和URL类 /352
16.2.2
URLConnection类 /353
16.2.3
InetAddress类 /354
16.3
TCP程序设计 /355
16.3.1
Socket 编程 /355
16.3.2
Socket类 /356
16.3.3
ServerSocket类 /358
16.4
UDP程序设计 /360
16.4.1
数据报通信基本概念 /361
16.4.2
DatagramPacket类 /361
16.4.3
DatagramSocket类 /362
16.4.4
MulticastSocket类 /362
16.5
本章小结 /363
16.6
习题 /363
第17章 JSP应用技术 /365
17.1
Java Web应用开发技术概述 /365
17.1.1
Java Web应用常见开发技术 /365
17.1.2
Java Web开发环境及开发工具 /367
17.1.3
Java Web应用程序的开发与部署 /368
17.2
静态网页开发技术 /369
17.2.1
HTML网页设计 /369
17.2.2
CSS样式表 /371
17.2.3
JavaScript脚本语言 /375
17.2.4
基于HTML JavaScript CSS的开发
案例 /377
17.3
JSP技术 /378
17.3.1
JSP技术概述 /378
17.3.2 JSP语法 /380
17.3.3
JSP内置对象概述 /385
17.3.4
request对象 /386
17.3.5
response 对象 /390
17.3.6
session对象 /392
17.3.7
application对象 /393
17.3.8
out对象 /394
17.3.9
JSP应用程序设计综合示例 /395
17.4
JavaBean技术 /398
17.4.1
JavaBean技术 /399
17.4.2
在JSP中使用JavaBean /400
17.4.3
多个JSP页面共享JavaBean /406
17.4.4
数据库访问JavaBean的设计 /407
17.5
Servlet技术 /411
17.5.1
Servlet技术 /411
17.5.2
Servlet常用对象及其方法 /412
17.5.3
基于JSP Servlet的用户登录验证
/414
17.5.4
在Servlet中使用JavaBean /415
17.5.5
JSP与Servlet的数据共享 /415
17.5.6 JSP与Servlet的关联关系 /418
17.5.7
基于JSP Servlet JavaBean实现复数运算 /418
17.6
本章小结 /421
17.7
习题 /421
附录A ASCII编码表 /422
附录B Java关键字 /423
附录C Java运算符及其优先级 /425
参考文献 /426
Java语言是国内外广泛使用的计算机程序设计语言之一,是当前Web类应用系统开发的语言。由于Java语言功能丰富、表达能力强、使用灵活方便、应用面广、可移植性好等许多特点,自1995年以来,Java语言迅速在全世界普及推广。目前Java语言是全球秀的程序设计语言之一。本书是编者在一线教学实践的基础上,为适应当前本科教育教学改革创新的要求,更好地践行语言类课程注重实践教学与创新能力培养的要求,组织新编而成的语言教程。教程编写中融合了同类其他教材的优点,并努力求变创新,新编教材具有如下特点:(1)突出Java语言实用的重点概念,在重点概念讲清楚的基础上,并不求语法概念的详尽与周全,而只求轻快明晰、循序渐进、通俗易懂、深入浅出。(2)全书内容可分为基础篇(第1~6章)、核心篇(第7~10章)、应用篇(第11~17章)三部分。(3)精选例题,引入了较多应用性实例,注重与加强程序阅读、参考、编写和实践的能力,重在面向对象编程思维的培养与训练。(4)从实际操作出发,发现问题解决问题,举一反三,一题多解,增强实用能力。(5)能明晰Java语言各主要语言成分的意义与价值,以“类 对象”为核心提高读者的编程能力。(6)基本知识介绍、典型习题与知识点把握等多方面相结合,使读者扎实掌握相关知识。(7)语言编程环境以NetBeans、Eclipse或MyEclipse为主。全书内容共分17章,主要内容包括Java概述、语言基础、选择控制、循环控制、方法、数组、对象和类、继承和多态、抽象类和接口、Java异常处理、常用类和接口、图形用户界面、文件输入输出、多线程编程、数据库编程、网络程序设计、JSP应用技术等。本书内容充实全面,主要章节除基本知识外,还有章节要点与引言、应用实例、本章小结、适量习题等,以配合读者对知识点的掌握。课程讲授时可根据学生、专业、课时等情况对内容适当取舍。本教程对教师提供全部PPT演示稿、参考答案、例题程序、实验安排等。本书可作为高等院校理工科各专业“Java语言程序设计”类课程的教材,也可供参加自学考试人员、应用系统开发设计人员、工程技术人员及其他对程序设计感兴趣的读者参阅。本书由钱雪忠主持编写,由江南大学、无锡太湖学院、华东理工大学等相关师生合作编写,参编人员有钱雪忠、李荣、沈佳宁、陈国俊等,参与编辑与程序调试的有钱恒、秦静、罗靖、韩利钊、樊路、马富天、王卫涛、金辉、吴进、姚琳燕等研究生。编写中还得到江南大学物联网工程学院“智能系统与网络计算研究所”同仁们的大力协助与支持,使编者获益良多,谨此表示衷心的感谢。由于时间仓促,编者水平有限,书中难免有疏漏和欠妥之处,敬请广大读者与同行专家批评指正。联系方式Email:[email protected], [email protected]。
作 者 2016年8月编者于江南大学
int sum = 0, sumAll = 0;for(int i =1; i<=1000; i ) sum =i;System.out.println(“1到1000的累加和是:” sum); sumAll = sum;sum = 0;for(int i =500; i<=1500; i ) sum =i;System.out.println(“500到1500的累加和是:” sum); sumAll = sum;sum = 0;for(int i =1000; i<=2000; i ) sum =i;System.out.println(“1000到2000的累加和是:” sum); sumAll = sum;System.out.println(“1到1000、500到1500、1000到2000各自累加和之总和是:” sumAll);
这样,你很容易发现,程序很重复、很相似。如果可以编写一个通用的代码程序,来复用而实现相同的功能有多好。Java语言有方法来实现这种愿望。方法(如同一般程序设计语言中的函数、过程或子程序)就是用来创建可重用代码的一种机制。例5-1 如下对应上面功能的程序段:
public class TestSum { public static int sum(int i1,int i2) { //定义含i1和i2两参数的sum方法 int sum = 0; for(int i =i1; i<=i2; i ) sum =i; System.out.println(i1 “到” i2 “的累加和是:” sum);//输出也可移到main方法中 return sum; } public static void main(String[] args){//main是程序的主方法,是程序的执行起点 int sumAll = 0; //如下3句可写成一句:sumAll =sum(1,1000) sum(500,1500) sum(1000,2000); sumAll =sum(1,1000);//调用方法计算1到1000的累加和,返回的累加和再加入到sumAll sumAll =sum(500,1500); sumAll =sum(1000,2000); System.out.println(“1到1000、500到1500、1000到2000各自累加和之总和是:” sumAll); }}
方法是为完成一个功能而组合在一起的语句组。在前面章节里,已使用过预定义的方法,如System.out.println、JOptionPane、showMessageDialog、Double.parseDouble、Math.random等,这些是Java库中预定义的。本章将学习如何定义自己的方法以及应用方法抽象来解决复杂问题。5.1 方法定义一般情况下,定义一个方法包含以下语法:
修饰符 返回值类型 方法名 (参数类型 参数名,…){ … 方法体 … return 返回值;}
方法包含一个方法头和一个方法体。下面是一个方法的所有部分。修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。返回值类型:方法可能会返回值。返回值类型是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值,在这种情况下,返回值类型是void。方法名:是方法的实际名称。方法名和参数列表共同构成方法签名。参数类型:参数类型是给参数指定的数据类型,各参数像是一个个占位符。当方法被调用时,传递值给各参数。这个值被称为实参值或实参变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数,但要保留空的括号“( )”。方法体:方法体包含具体的语句,定义该方法的具体功能。图5-1给出了如何定义一个方法。
图5-1 方法定义示意图如:
public static int age(int birthday){…}
参数可以有多个,如:
static float interest(float principal,int year){…}
注意:在一些其他语言中,方法指过程、子程序和函数。一个返回非void类型返回值的方法称为函数;一个返回void类型返回值的方法叫做过程。例如,下面的方法包含两个参数num1和num2,它返回这两个参数的值。
public static int max(int num1, int num2){/* 返回两个整型变量数据的较大值 */ int result; if (num1 > num2) result = num1; else result = num2; return result;}
5.2 方法调用Java支持两种调用方法的方式,根据方法是否返回值来选择。(1)当程序调用一个方法时,程序的控制权交给了被调用的方法。当被调用方法的返回语句执行或者到达方法体闭括号的时候交还控制权给调用程序。当方法返回一个值的时候,方法调用通常被当作一个值或一个值表达式。例如:
int larger = max(30, 40);
(2)如果方法的返回值是void,则方法调用一定是一条语句形式。例如,方法 println()返回void。下面的调用是以语句方式进行的:
System.out.println(“Welcome to Java!”);
5.2.1 有返回值方法例5-2 下面的例子演示了如何定义一个有返回值的方法,以及如何调用它。
public class TestMax { public static void main(String[] args) { /** 主方法 */ int i = 5,j = 2; int k = max(i, j); System.out.println(“The maximum between ” i ” and ” j ” is ” k); } public static int max(int num1, int num2){ /** 返回两个整数变量较大的值 */ int result; if (num1 > num2) result = num1; else result = num2; return result; }}
以上实例编译运行结果为:
The maximum between 5 and 2 is 5
这个程序包含main方法和max方法。main方法是被JVM调用的,除此之外,main方法和其他方法没什么区别。main方法的头部是不变的,如上例所示,带修饰符public和static,返回void类型值,方法名字是main,此外带一个String[]类型参数。String[]表明参数是字符串数组。5.2.2 无返回值方法如何声明和调用一个无返回值(void)方法呢?下面的例子声明了一个名为printGrade的方法,并且调用它来打印给定的分数。例5-3 无返回值(void)方法调用示例。
public class TestVoidMethod { public static void main(String[] args) { printGrade(78.5); // 方法以独立语句形式调用 } public static void printGrade(double score) { if (score >= 90.0) { System.out.println(‘A’); } else if (score >= 80.0) System.out.println(‘B’); else if (score >= 70.0) System.out.println(‘C’); else if (score >= 60.0) System.out.println(‘D’); else System.out.println(‘F’); }} // 运行结果为:C
这里printGrade方法是一个void类型方法,它不返回值。一个void方法的调用一定是一个独立语句,而有返回值的方法,可以出现在表达式中来完成调用。所以,这里printGrade方法被在main方法中第2行以语句形式调用。就像任何以分号结束的语句 一样。5.2.3 嵌套调用Java语言中不允许嵌套的方法定义。因此各方法之间是平行的,不存在上一级方法和下一级方法的问题。但是Java语言允许在一个方法的定义中出现对另一个方法的调用。这样就出现了方法的嵌套调用。即在被调方法中又调用其他方法。这与其他语言的子程序嵌套的情形是类似的。其关系可表示如图5-2所示。
图5-2 方法间调用示意图图5-2表示了两层嵌套的情形。其执行过程是:执行main方法中调用a方法的语句时,即转去执行a方法,在a方法中调用b方法时,又转去执行b方法,b方法执行完毕返回a方法的断点(即调用点)继续执行,a方法执行完毕返回main方法的断点继续执行。例5-4 计算s=22! 32!本题可编写两个方法:一个是用来计算平方值并调用方法fun2的方法fun1,另一个是用来计算阶乘值的方法fun2。主方法先调fun1计算出平方值,再在fun1中以平方值为实参,调用 fun2计算其阶乘值,然后返回fun1,再返回主方法,在循环程序中计算累加和。
public class TestNestedCallMethod { public static void main(String[] args) { int i; long s=0; for (i=2;i<=3;i ) s=s fun1(i); System.out.printf(“ns=%dn”,s); } static long fun1(int p) { int k; long r; k=p*p; r=fun2(k); return r; } static long fun2(int q) { long c=1; int i; for(i=1;i<=q;i ) c=c*i; return c; }}
说明:在主程序中,执行循环程序依次把i值作为实参调用方法fun1求i2值。在fun1中又发生对方法fun2的调用,这时是把i2的值作为实参去调fun2,在fun2 中完成求i2!的计算。fun2执行完毕把C值(即i2!)返回给fun1,再由fun1返回主方法实现累加。至此,由方法的嵌套调用实现了题目的要求。由于数值可能会很大,所以方法和一些变量的类型都说明为长整型,否则会造成溢出而产生计算错误。5.2.4 递归调用使用递归就是使用递归方法编程,递归方法就是直接或间接调用自身的方法。许多数学函数都是使用递归来定义的。这样的函数在Java中也能来定义与调用。这里以n的阶乘来举例说明,数字n的阶乘递归定义为:?0!=1;?n!=n×(n?1)×…×2×1 = n×(n?1)!设计算n!的方法是factorial(n),根据n阶乘的递归定义公式,计算factorial(n)的递归算法可以简单地描述如下:
if (n==0) return 1;else return n* factorial(n-1);
例5-5 输入一个非负整数,显示该数的阶乘值。
import java.util.Scanner;public class ComputerFactorial { public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print(“请输入一个非负整数:”); int n = input.nextInt(); System.out.print(n “的阶乘值是:” factorial(n)); } public static long factorial(int n) { if (n==0) return 1; else return n * factorial(n-1); }}
设func方法功能同factorial递归定义方法,则func(5)方法的递归调用过程如图5-3所示。
图5-3 方法递归调用示意图5.3 方法参数传递5.3.1 基本数据类型参数传递方法的形式参数是基本数据类型时,形式参数就相当于方法定义范围内的变量(即局部变量),形参变量只在方法内有效,形参变量在方法调用结束时也就被释放了,不会影响到调用方法的主程序中同名或不同名的变量(即实参变量)。方法的形式参数是基本数据类型时,参数传递是所谓的值传递方式,即只是把参数值传给调用的方法,而不会把方法对参数可能有的改变值回传回来。看看下面的程序 代码。例5-6 自定义类SimpleValue。本程序的功能是定义一个简单值类SimpleValue,实现基本数据的参数传递。
class SimpleValue{ public static void main(String[] args){ int x = 5; change(x); System.out.println(x); //输出为5,而不是方法中改变的3 } public static void change(int x){ x = 3; }}
例5-7 本例演示按值传递的效果。该程序创建一个方法,该方法用于交换两个 变量。
public class TestPassByValue { public static void main(String[] args) { int num1 = 1, num2 = 2; System.out.println(“Before swap method, num1 is ” num1 ” and num2 is ” num2); swap(num1, num2); // 调用swap方法 System.out.println(“After swap method, num1 is” num1 “and num2 is” num2); } public static void swap(int n1, int n2) { /** 方法内交换两个变量的方法 */ System.out.println(“tInside the swap method”); System.out.println(“ttBefore swapping n1 is ” n1 ” n2 is ” n2); int temp = n1; n1 = n2; n2 = temp; // 开始交换 n1 与 n2的值 System.out.println(“ttAfter swapping n1 is ” n1 ” n2 is ” n2); }}
以上实例编译运行结果如下:
Before swap method, num1 is 1 and num2 is 2 Inside the swap method Before swapping n1 is 1 n2 is 2 After swapping n1 is 2 n2 is 1After swap method, num1 is 1 and num2 is 2
传递两个参数调用swap方法。有趣的是,方法被调用后,实参的值并没有改变。请思考为什么?调用一个方法时候需要提供实参值,必须按照参数列表指定的顺序对应提供实参值。例如,下面的方法连续n次打印一个消息:
public static void nPrintln(String message, int n) { for (int i = 0; i < n; i ) System.out.println(message);}
调用形式如:“nPrintln(“Good!”,3);”或“对象.nPrintln(“I am a student.”,5);”等。请注意实参的顺序。5.3.2 引用数据类型参数传递对象是通过对象引用变量(reference variable)来访问的,使用如下语法格式声明这样的对象引用变量:
类名 对象引用变量;
接着,再把创建的对象的引用赋值给引用变量,如:
对象引用变量=new 类名();
也可以写一条语句,包括声明对象引用变量、创建对象以及将对象的引用赋值给这个引用变量,格式如:
类名 对象引用变量=new 类名();
如:
Circle myCircle = new Circle();//myCircle中放的是Circle对象的一个引用
对象的引用变量并不是对象本身,它们只是对象的句柄(名称)。就好像一个人可以有多个名称一样(如中文名、英文名等),一个对象也可以有多个句柄或引用名。注意:对象引用变量与对象是不同的(如同人名与其对应的人是两个概念),但是大多数情况下,这种差异是可以忽略的。因此可以简单地说myCircle是一个Circle对象(就如说某个具体人名就认为是该人一样)。例5-8 自定义类ReferenceValue。
class ReferenceValue{ int x ; public static void main(String[] args){ ReferenceValue obj = new ReferenceValue(); obj.x = 5; System.out.println(“chang方法调用前的x = ” obj.x); change(obj); System.out.print(“;chang方法调用后的x = ” obj.x); } public static void change(ReferenceValue obj){ obj.x=3; }}// 输出的结果是:chang方法调用前的x = 5;chang方法调用后的x = 3
注意:实际上,所有传递给方法的参数都是值传递的。对于基本类型的参数,传递的是参数具体的值;而对于引用数据类型的参数,则传递的是对象的引用。只是传递引用变量的效果大不一样。请读者多思考思考。5.4 方法重载上面使用的max方法仅仅适用于int型数据。如果你想得到两个浮点类型数据的值呢?解决方法是创建另一个有相同名字但参数类型不同的方法,如下面代码所示:
public static double max(double num1, double num2) { if (num1 > num2) return num1; else return num2;}
这样,如果你调用max方法时传递的是int型参数,则int型参数的max方法就会被调用;如果传递的是double型参数,则double类型的max方法会被调用,这叫做方法重载。就是说,一个类的两个方法拥有相同的名字,但是有不同的参数列表。Java编译器根据方法签名判断哪个方法应该被调用。方法重载可以让程序更清晰易读。执行密切相关任务的方法应该使用相同的名字,调用同名但不同的方法可由参数的不同自动去匹配其实现。重载的方法必须拥有不同的参数列表。但要注意,不能仅仅依据修饰符或者返回类型的不同来重载方法。
5.5 变量作用域变量的范围是程序中该变量可以被引用(或有效使用)的区域。方法内定义的变量被称为局部变量。请注意:(1)局部变量的作用范围从声明开始,直到包含它的块(一般块由{ }来体现) 结束。(2)局部变量必须先声明才可以使用。(3)方法的形式参数(定义方法时参数列表中的参数称为形式参数)的作用域涵盖整个方法体,形式参数实际上也是方法的一个局部变量。(4)for循环的初始化部分声明的变量,其作用范围在整个for循环。但循环体内声明的变量的适用范围是从它声明到循环体结束。for循环包含如图5-4所示的变量声明。
图5-4 for循环内变量作用域注意:可以在一个方法里的不同的非嵌套块中多次声明一个具有相同名称的局部变量,但不能在嵌套块内两次声明局部变量。5.6 命令行参数有时候你希望在运行一个程序时再传递给它消息。这要通过运行时传递命令行参数给main()函数来实现。在main()方法的括号里面有一个形式参数“String args[]”,args[]是一个字符串数组,可以接收系统所传递的参数,而这些参数则来自于用户的输入,即在运行程序的过程中将用户输入传递到一个程序中。在命令行执行一个程序通常的形式是:
Java 类名 [参数列表]
其中的参数列表中可以容纳多个参数,参数间以空格或制表符隔开,它们被称为命令行参数。系统传递给main()方法的实际参数正是这些命令行参数。由于Java中数组的下标是从0开始的,所以形式参数中的args[0],…,args[n-1]依次对应第1,…,n个参数。如图5-5所示。例5-9 本例展示了main()方法是如何接收这些命令行参数并打印出来的。
评论
还没有评论。