1.1 Java语言简介
Java语言是当前非常流行的开发语言,不过发展到今天也走过了非常曲折的道路。下面就从语言的发展、特点、工作原理几个方面详细介绍一下Java语言。
JAVA从入门到实践
1.1.1 Java语言的发展
计算机编程语言不断发展,Java语言发展到今天也走过了非常曲折的道路。事物的产生都有其必然的因素,Java语言的出现也验证了这一点。透过Java语言的发展历程,可以更详尽的了解什么是Java。
Java语言发展到今天,可以说互联网的快速发展起了很大的推动作用。现在谈到Java,已不仅仅表示一门程序语言,更是一种软件开发平台。Java已经演化出了J2SE、J2EE、J2ME三个版本,分别面向不同领域的应用开发。
1.Java 2 Platform,Standard Edition(J2SE)
2.Java 2 Platform,Enterprise Edition(J2EE)
3.Java 2 Platform,Micro Edition(J2ME)
JAVA从入门到实践
1.1.2 Java语言的特点
Java语言是一种分布式的面向对象编程语言,在各个行业领域开发中得到了广泛的应用。作为一种 程序设计语言,Java具有面向对象、平台无关、简单、健壮、多线程、安全等诸多特性。下面就这些方面特性分别进行讨论。
1.面向对象 2.平台无关性
3.简单性 4.解释执行
5.网络的 6.分布式
7.健壮性 8.可扩展性
9.安全性
JAVA从入门到实践
1.1.3 工作原理
虚拟机(JVM)与垃圾回收是Java语言工作的两种重要机制,下面对其分别进行详细介绍。
1.Java虚拟机(JVM)
2.垃圾回收机制
JAVA从入门到实践
1.2 Java程序运行环境
在使用一门语言之前,首先需要搭建相关的运行环境。下面就从JDK的安装、环境变量设置、开发工具几个方面介绍如何搭建Java语言的运行环境。
JAVA从入门到实践
1.2.1 下载、安装JDK
要进行Java应用程序开发,首先需要安装JDK(Java Development Kits)。JDK是Sun公司提供的一套Java开发环境,具有多种操作系统的多个版本。自从Java诞生以来,JDK的版本一直在不断升级,如JDK1.3、JDK1.4、JDK1.5。下面以J2SE 6.0 Development Kits在Windows操作系统下的安装为例,逐步搭建Java程序的运行环境。
JAVA从入门到实践
1.2.2 设置环境变量
Java程序运行的环境变量主要包括Path和Classpath。Path用于指定JDK包含的工具程序所在的路径,这与设置操作系统中其他应用程序的Path是一样的。Classpath是Java程序运行所特需的环境变量,用于指定运行的Java程序所需的类的加载路径。设置Java运行环境变量有命令行和图形界面两种形式,下面分别进行介绍。
1.设置Path
2.设置Classpath
JAVA从入门到实践
1.2.3 开发工具介绍
Eclipse是一个流行的针对Java编程的集成开发环境(IDE)。它还可以用作编写其他语言(比如C++和Ruby)的环境,合并各种种类工具的框架,以及创建桌面或服务器应用程序的富客户端平台。Eclipse是开放源代码的项目,可以免费下载。它的官方网址是http://www.Eclipse.org,目前最新的版本号是3.4。
JAVA从入门到实践
1.3 第一个Java程序
在全面学习一门编程语言之前,最快的对该语言进行大致了解的方式就是编写一个简单的程序。下面就以第一个Java程序为例,详细介绍Java程序的编写、编译、运行等过程。
JAVA从入门到实践
1.3.1 编写程序
配置好程序运行环境后就可以动手编写Java程序了。通过编写第一个简单的Java程序,能够对Java有个快速的体验,也能验证运行环境配置的正确与否。学习一门程序语言,通常都是以一个“HelloWorld”的程序开始。为了让读者能够更深的体会Java程序的编写、执行过程,下面的实例先是采用文本编辑器编写、命令行方式执行。最后将会介绍使用Eclipse编写该实例的过程。
JAVA从入门到实践
1.3.2 编译、运行
程序编写完成后,在执行前首先需要进行编译。编译Java源程序需要使用Javac命令程序。命令行方式编译、运行Java源程序的步骤如下所示。
JAVA从入门到实践
1.3.3 使用Eclipse编写、执行程序
在掌握了用命令行方式编译、执行程序的
后,下面详细介绍一下如何使用Eclipse编写、执行上面列举的HelloWorld程序。
JAVA从入门到实践
1.3.4 程序结构
第一个Java程序比较简单,但毕竟是一个完整的程序,能够正确执行。下面对这个程序的整个结构做个简单说明,以便对Java程序结构有个最初步的简单认识。
01 public class HelloWorld { //定义类HelloWorld
02 //定义main()方法
03 public static void main(String args[]) {
04 System.out.println("Hello World!"); //输出字符串
05 }
06 }
JAVA从入门到实践
1.3.5 Java程序调试技巧
程序调试是程序开发过程中很重要的一项工作,即时熟练的开发人员也是如此。不过,对于初学者来说有时更容易犯一些入门级的错误。很小的一个错误往往使初学者费尽周折,为此花费大量精力。下面给出一些编写程序过程中经常遇到的一些问
及调试技巧,以便在遇到问题时能够快速饩觥
1.Path、Classpath的问题
2.注意大小写
3.主文件名与类名一致
4.全角与半角
5.使用Eclipse调试程序
JAVA从入门到实践
1.6 小结
本章介绍了Java语言的发展、特点、运行环境等方面
。另外,通过一个实例程序演示了Java程序的编写、编译、执行、调试过程。本章的重点是掌握Java程序运行环境的搭建。从下一章开始,本书将全面展开Java语言具体内容的学习。
JAVA从入门到实践
1.7 本章习题
1. Java语言都有哪些特点?按应用领域来分,有哪些版本?
2. 如何搭建Java程序的运行环境?
3. 什么是Classpath,该如何设置?
JAVA从入门到实践
第2章 简单数据类型及运算
在Java语言中定义了一组简单数据类型,这些数据类型是构成其他数据类型的基础。简单数据类型类似结构化编程语言中的数据类型。定义了数据类型的变量与常量,与运算符进行组合,可以形成各种复杂的表达式,从而构成程序中的基本运算单元。在各种编程语言中,可以说数据类型、运算符及表达式等都是程序基础。会同标识符、关键字、变量与常量,这些基础知识又互相衔接,密不可分。本章针对这些基础知识逐一详细介绍。
JAVA从入门到实践
2.1 标识符与关键字
程序中的标识符与关键字都具有一定的含义。标识符是用户定义的程序中类、变量、常量、方法等的标识,关键字是语言本身留作特殊用途的专用符号。关于标识符与关键字的具体知识,下面分别进行介绍。
JAVA从入门到实践
2.1.1 标识符
标识符是指程序中类、变量、常量、方法等的名字。类、变量、常量、方法等进行定义和引用时需要利用一定的标识进行识别,这就需要使用标识符。标识符的命名必需符合一定的规范,Java语言的标识符命名规则如下。
首字符必需是字母、下划线_、美元符号$、或者人民币符号¥。
标识符由数字0~9、大写字母A~Z、小写字母a~z和下划线_、美元符号$以及所有在十六进制0xc0前的ASCII码等组成。
不能把关键字和保留字作为标识符。
标识符对大小写敏感,也就是需要区分大小写。
标识符没有长度限制。
JAVA从入门到实践
2.1.2 关键字
语言本身专门使用的标识符为关键字,在程序代码中有其特殊的含义。Java常用的关键字有package、class、interface、public、private、protected、default、int、byte、double、boolean、char、if、else、while、switch、case、do、break、continue、try、catch、finally、throw、throws、new、this、super等。所有的关键字都为小写,每个都有其特殊的作用,比如:
用于包、类、接口定义:package、class、interface。
访问控制修饰符:public、private、protected、default。
数据类型:int、byte、double、boolean、char。
关于流程控制:if、else、while、switch、case、do、break、continue。
关于异常处理:try、catch、finally、throw、throws。
创建对象:new。
引用:this、supe。
JAVA从入门到实践
2.2 基本数据类型
程序中的主要数据元素为变量与常量,每一个变量与常量必须属于一种数据类型。数据类型指定了该类数据所占内存空间的大小、取值范围及其可以进行的操作。Java语言中的数据类型可分为基本数据类型和复合数据类型。基本数据类型可称为“原始数据类型”,是其他数据类型的基础。复合数据类型以基本数据类型为基础,通常以类的形式进行封装。复合数据类型的概念后续章节会详细说明。基本数据类型主要包括布尔类型、字符型、整型、实型,下面分别进行介绍。
JAVA从入门到实践
2.2.1 布尔类型
布尔类型用关键字boolean表示,只有true和false两个值。布尔类型通常用在流程控制中进行逻辑判断。布尔型数据在机器中占1个字节,系统默认初始值为false。
JAVA从入门到实践
2.2.2 字符型
字符型用关键字char表示。Java中的字符属于Unicode编码(一种类似于ASCII码的国际
编码,采用二字节编码)。由于计算机底层只能处理二进制数据,要想使用字符,就需要对字符进行编码,转换成一系列二进制数来表示特定的字符。目前有多种编码字符集,如Unicode、ISO-8859-1、GBK、ASCII等。不同的字符集收录的字符不尽相同,Unicode属于国际标准字符集,收录了世界上所有各国语言文字的字符。字符型数据在机器中占2个字节,默认初始值为’\u0000’。
JAVA从入门到实践
2.2.3 整型
整型用来表示不含小数部分的数字。Java语言中共有四种整数类型,分别是byte、short、int和long。这四种整数类型占用的内存空间各不相同,从而取值范围也不同。
数据类型 占用空间 取值范围 默认值
byte 1个字节 -128~127 0
short 2个字节 -215~215-1 0
int 4个字节 -231~231-1 0
long 8个字节 -263~263-1 0
JAVA从入门到实践
2.2.4 实型(浮点型)
实型用来表示含有小数的数字。Java语言中共有float和double两种实数类型。这两种实数类型占用的内存空间、取值范围各不相同。
数据类型 占用空间 取值范围 默认值
float 4个字节 3.4e-038~3.4e+038 0F
double 8个字节 1.7e-308~1.7e+308 0D
JAVA从入门到实践
2.2.5 数据类型转换
在程序编写过程中,不同数据类型的变量之间经常需要赋值或运算,这就需要进行数据类型转换。各种数据类型根据分配空间大小、取值范围不同,划分为一定的优先级关系。再根据优先级,数据类型转换分为自动类型转换和强制类型转换。
1.自动类型转换
2.强制类型转换
由低到高—————————————————————>
byte short (char) int long float double
JAVA从入门到实践
2.3 运算符与表达式
运算符与表达式的概念是紧密联系在一起的。运算符与操作数组成表达式来完成相应的运算。不同类型的运算符,组成不同的表达式,可以完成不同类型的运算。表达式是具有确定值的语句,由操作数和各种运算符按照一定的规则组成。表达式的值可以作为操作数,进而形成更复杂的表达健Java语言中的运算符主要包括如下类别:
算术运算符。
赋值运算符。
关系运算符。
逻辑运算符。
位运算符。
条件运算符。
JAVA从入门到实践
2.3.1 算术运算符及表达式
算术运算符和操作数组成算术表达式,完成基本的算术运算。算术运算符按照操作数的个数可以分为二元运算符和一元运算符,下面分别进行介绍。
1.二元算术运算符
2.一元算术运算符
JAVA从入门到实践
2.3.2 赋值运算符及表达式
由赋值运算符组成的表达式为赋值表达式。赋值运算符只有一个,即=。赋值运算符用于运算符右边的值赋值给左边的变量。
JAVA从入门到实践
2.3.3 关系运算符及表达式
由关系运算符及两个操作数组成关系表达式。关系运算符都是二元运算符,用来比较两个操作数,执行结果为布尔型。关系运算符共有六种,分别是>(大于)、<(小于)、>=(大于等于)、<=(小于等于)==(等于)和!=(不等于)。关系表达式的语法格式如下所示。
operation1 Operator operation2
其中,参数operation1表示第一个操作数。参数Operator表示关系运算符。参数operation2表示第二个操作数。
JAVA从入门到实践
2.3.4 逻辑运算符及表达式
由逻辑运算符及操作数组成逻辑表达式。逻辑运算符共有三个,分别是&&(逻辑与)、||(逻辑或)和!(逻辑非)。其中&&(逻辑与)、||(逻辑或)是二元运算符,!(逻辑非)是一元运算符。逻辑表达式的操作数都必须为布尔型,执行结果也为布尔型。
JAVA从入门到实践
2.3.5 位运算符及表达式
位运算是指将操作数以二进制位的形式进行运算。位运算的操作数只能是整数类型。位运算符共有七个,分别是>>(位右移)、<<(位左移)、>>>(无符号位右移)、&(按位与)、|(按位或)、^(按位异或)和~(按位取反)。其中前六项均为二元运算符,而~(按位取反)是一元运算符。
JAVA从入门到实践
2.3.6 条件运算符及表达式
条件运算符为三元运算符,由条件运算符和三个操作数组成三元条件表达式。三元条件表达式运算时首先判断条件式(第一个操作数,为布尔型)的值,如果为true,则整个表达式的结果为冒号前的值,否则为冒号后的值。三元条件表达式的语法格式如下所示。
operation1 ? operation2 : operation3
其中,参数operation1表示第一个操作数,值必需为布尔类型,可以为表达式。参数operation2表示第二个操作数,当第一个操作数的值为true时,其值作为表达式的结果。参数operation3表示第三个操作数,当第一个操作数的值为false时,其值作为表达式的结果。
JAVA从入门到实践
2.3.7 运算符的优先级
最简单的表达式是一个变量或常量,变量或常量的值就是表达式的值。前面讲过,表达式的值可以作为操作数,从而组成更加复杂的表达式。复杂的表达式中往往包含多个运算符,它们的计算需要有一定的先后顺序,这就是运算符的优先级。
优先级顺序 运算符
1 . [] ()
2 ++ -- ~ instanceof
3 new (type)
4 * / %$
5 + -
6 >> >>> <<
7 > < >= <=
8 == !=
9 &
10 ^
11 |
12 &&
13 ||
14 ?:
15 = += -= *= /= %= ^=
16 &= |= <<= >>= >>>=
JAVA从入门到实践
2.4 变量与常量
变量与常量是程序中的基本数据元素。变量代表运行过程中值可以改变的数据,常量代表运行过程中值恒定不变的数据。关于变量与常量的具体知识,下面分别进行介绍。
JAVA从入门到实践
2.4.1 定义变量
变量是编程语言中十分重要的概念,代表一定的存储空间,里面用来存储相应数据。类中的变量用来表示类的属性,在程序运行过程中,变量所对应的值是可以变化的。定义变量的语法如下所示。
type Variablename = initialvalue;
其中,参数type表示变量的类型,可以是基本类型,也可以是复杂类型。关于数据类型,下面会详细说明。参数Variablename表示变量名称,需要符合标识符的命名规范。参数=为赋值运算符,这里用于初始化,运算符的概念后续章节会详细说明。参数initialvalue表示初始化值。
JAVA从入门到实践
2.4.2 变量的作用域
变量的作用域规定了变量能被使用的范围,只有在作用域范围内,变量才能够被调用。作用域在变量声明时即被指定。根据作用域的不同,变量可以分为不同的类型:类变量、局部变量、方法参数变量、异常处理参数变量。下面分别对这几类变量进行详细介绍。
1.类变量
2.局部变量
3.方法参数变量
4.异常处理参数变量
JAVA从入门到实践
2.4.3 定义常量
常量可以说是一种特殊的变量,一旦初始化以后,不能再对其进行赋值。也就是说,常量在初始化后,其值不再改变,只能进行访问。定义常量的语法如下所示。
final type Constantname = initialvalue;
其中,参数final为关键字,代表不可更改。参数type表示常量的类型。参数Constantname表示常量名称,可以任意取,不过需要符合标识符的命名规范。参数=为赋值运算符,这里用于初始化,运算符的概念后续章节会详细说明。参数initialvalue表示初始化值。
JAVA从入门到实践
2.5 本章实例
本章主要讲解了简单数据类型及各种运输符与表达式,还有变量与常量的定义。下面给出一个较完整的实例,进一步加深掌握本章内容。
1.编写程序
2.程序说明
3.执行结果
JAVA从入门到实践
2.8 小结
本章首先介绍了Java语言中标识符与关键字、变量与常量的知识。然后重点讨论了各种基本数据类型,又讨论了各种运算符及相应表达式,最后给出了一个完整的实例。其中,变量的作用域是本章的难点,需要在编程过程中多加体会。下一章将以本章为基础,讲解有关程序流程控制方面的内容。
JAVA从入门到实践
2.9 本章习题
1.举例说明什么是非法的标识符
2.定义两种不同数据类型的变量,完成它们之间的类型转换
3.二元运算符都有哪些?一元运算符又有哪些?
4.定义一个公式,能够根据摄氏温度计算出华氏温度。已知,华氏温度转化为摄氏温度的计算公式为:C = (F - 32) * 5/9。其中,C代表摄氏温度,F代表华氏温度。
JAVA从入门到实践
第3章 流程控制
为了解决现实问题,程序的执行流程应该是多种多样的。流程应该既可以自上而下的顺序执行,又应该能够遇到某些条件进行跳转,还应该能够对某些操作重复执行。为了控制程序的执行流程,需要使用流程控制语句。流程控制主要包括顺序结构、选择结构、循环结构以及跳转语句,本章针对这些基础知识逐一详细介绍。本章包括以下知识点。
顺序结构;
选择结构;
循环结构;
跳转语句;
注释语句。
JAVA从入门到实践
3.1 顺序结构
顺序结构是程序中最常见的流程结构,语句按照出现的先后顺序自上而下执行。顺序语句执行的过程中没有跳转和判断,直到程序执行结束为止。
JAVA从入门到实践
3.2 选择结构
选择结构也称为分支结构,根据一个判断表达式的结果选择不同的分支语句执行。选择结构提供了程序跳转机制,根据选择的结果,有些语句可能被跳转过去不被执行。选择结构主要包含两种语句,if语句和switch语句,下面分别进行介绍。
JAVA从入门到实践
3.2.1 if语句
If语句是最经常使用的选择结构。它包含两个分支,根据指定布尔类型表达式的结果true或false,选择不同的分支执行。If语句根据复杂程度,可以具有多种形式,如if、if-else、if-else-if。下面分别进行介绍。
1.if形式
2.if-else形式
3.if-else-if形式
JAVA从入门到实践
3.2.2 switch语句
switch语句属于多分支结构,通常可以替代复杂的if-else-if形式的语句。switch语句根据表示的值选择一个分支来执行,表达式的结果类型只能为byte、short、int或char型。switch语句的语法格式如下所示。
switch (表达式) {
case value1:
//处理语句1
break;
case value2:
//处理语句2
break;
case value3:
//处理语句3
break;
…
default:
//处理语句n
}
JAVA从入门到实践
3.3 循环结构
要重复执行一段代码,需要使用循环结构。循环结构可以重复执行指定的处理语句,直到不再满足循环条件为止。循环结构主要有for和while两种循环语句,下面分别进行介绍。
JAVA从入门到实践
3.3.1 for循环语句
for语句通常用于重复次数确定的循环。for循环的语法格式如下所示。
for (初始化;循环条件;迭代部分) {
循环体
}
其中,参数for为关键字。参数“初始化”表示循环的初始化语句,只在循环开始前执行一次,通常用于迭代变量的定义。参数“循环条件”为布尔类型表达式,结果为true时执行循环体,结果为false时结束循环体。参数“迭代部分”在循环体执行完毕时执行。执行完迭代部分,再次判断循环条件,如此反复执行,直到循环条件不再满足。
JAVA从入门到实践
3.3.2 while循环语句
while语句通常用于重复次数不确定的循环。该语句包含两种形式,while形式和do…while形式。下面分别进行介绍。
1.while形式
2.do…while形式
JAVA从入门到实践
3.3.3 多重循环
各种循环语句可以嵌套使用,从而构成更加复杂的多重循环。比如for语句中还有for语句,while语句中还有while语句,for语句中包含while语句等。
JAVA从入门到实践
3.4 跳转语句
要进行流程跳转,需要使用跳转语句。Java语言包括三种跳转语句,分别是break、continue、return,下面分别进行介绍。
JAVA从入门到实践
3.4.1 break语句
在switch语句中,break语句用于结束switch语句的执行。这在上面switch章节已经介绍,在此不再赘述。在循环结构中,break用于强行终止循环。
JAVA从入门到实践
3.4.2 continue语句
continue语句用于循环结构中,作用是跳过本次循环,执行下一次迭代。
JAVA从入门到实践
3.4.3 return语句
return语句用于终止当前方法运行,返回到调用该方法的语句处。如果方法需要有返回值,return语句后就应该提供相应返回值。有关方法的概念,在后续章节中会详细介绍。
JAVA从入门到实践
3.5 注释语句
在介绍了Java语言的流程控制语句之后,现在来介绍一下Java程序中注释的使用。在Java程序的任意位置都可以加入注释语句,Java编译器会忽略这些注释语句。Java语言主要包括单行和多行两种注释,下面分别进行介绍。
JAVA从入门到实践
3.5.1 单行注释
在Java程序中使用“//”符号来进行单行注释。从“//”符号开始,到本行结束的所有字符均被编译器作为注释而忽略。
JAVA从入门到实践
3.5.2 多行注释
多行注释的方法是以“/*”符号为开头,以“*/”为结尾,中间为注释的内容。注释的内容没有数量限制,可以为任意多行数目,当然也可以是单行。
JAVA从入门到实践
3.6 本章实例
意大利著名数学家列奥纳多斐波纳契曾经在其著作《算法之书》中提出了“著名的兔子问题”:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
答案是一组非常特殊的数字,即:1、1、2、3、5、8、13、21、34…以上这些数字就是著名的“斐波纳契数列”。
1.编写程序
2.程序说明
3.执行结果
JAVA从入门到实践
3.7 上机实践
1.编写程序,实现求解以下分段函数:
y=
2.编写程序,用*号打印出金字塔图形
JAVA从入门到实践
3.8 小结
本章介绍了Java语言中的各种流程控制语句,包括选择结构的if/switch语句,循环结构的for/while语句及程序跳转语句break、continue、return。另外还介绍了注释语句的使用方法。本章最后给出了一个完整的实例。其中各种控制语句的综合运用是本章的难点。在编写程序解决现实问题时,常常需要综合运用各种流程控制语句,从而实现较复杂的处理逻辑。在掌握了基本语法后,读者应该多学习一些相关的算法知识,从而能够解决更加复杂地问题。下一章将介绍Java语言面向对象编程中类和对象的相关知识。
JAVA从入门到实践
3.9 本章习题
1. 某市不同车牌的出租车3km的起步价和计费分别为:夏利5元,3km以外2.1元/km;富康8元,3km以外2.4元/km;桑塔纳10元,3km以外2.7元/km。分别用if语句和switch语句编程实现:根据乘车的车型及行车公里数输出应付车资。
2. 用循环实现求100的阶乘。
3. break语句和continue语句的区别是什么?
JAVA从入门到实践
第4章 类与对象
类与对象是进行面向对象编程的基础。类是具有相同属性特征和行为规则的多个对象的一种统一描述,对象是对类的实例化。在Java语言中,类是一种最基本的复合数据类型,是组成Java程序的基本要素。下面详细介绍Java语言中有关类与对象的定义方法。本章包括以下知识点。
类的创建;
创建类的成员及方法;
关键字this;
对象的创建、使用及清除。
JAVA从入门到实践
4.1 创建类
面向对象的编程从创建类开始。创建了类,才谈得上封装、继承、多态,才能实例化生成对象。类的整体结构主要包括声明和类成员两大部分。本节详细介绍如何声明类及类成员的访问控制。
JAVA从入门到实践
4.1.1 声明类
要使用一个类,必须先声明类。声明类就是创建一种新的数据类型,利用声明的类可以定义类实例,也就得到了一个对象。声明类的语法如下所示。
{public} {abstract | final } class
{extends } {implements } {
//类主体
}
其中,参数public、abstract、final表示类修饰符是可选项,下面会详细说明。参数class是关键字。参数Classname表示类名。参数extends Classname表示继承自其他类。参数implements Interface表示实现了某些接口。继承和接口方面在后续章节会详细介绍。
JAVA从入门到实践
4.1.2 类成员的访问控制
对于类的成员,不管是成员变量还是成员方法,都有一定的访问控制权限。访问控制权限限定了指定对象可以被访问的范围。类成员的访问控制符有public、private、protected和default。
public:用public修饰的成分表示是公有的,也就是它可以被其他任何对象访问(前提是对类成员所在的类有访问权限)。
private:类中限定为private的成员只能被这个类本身访问,在类外不可见。
protected:用该关键字修饰的成分是受保护的,只可以被同一类及其子类的实例对象访问。
default:public、private、protected这三个限定符不是必须写的。如果不写则表明是default,相应的成分可以被所在的包中各类访问。
JAVA从入门到实践
4.2 创建类的成员
类的成员变量定义了类的属性。所定义的成员变量,可以被类内的所有方法访问。比如,如果把电视机看作一个类,则电视机的颜色就是这个类的一个成员变量。该变量用来描述电视机的颜色。声明成员变量的语法如下所示。
{public | protected | private} {static} {final} {transient} {volatile} type variableName;
其中,参数public、private、protected表示成员变量的访问权限。参数static表示限定该成员变量为类变量。参数final表示声明为常量。参数transient表示声明为暂时性变量。参数volatile表示声明一个共享变量。参数type表示变量的类型。参数variableName表示变量名称。
JAVA从入门到实践
4.3 创建类的方法
除了成员变量,方法也是类的重要成员。成员方法描述了对象所具有的功能或操作,反映对象的行为,是具有某种相对独立功能的程序模块。本节详细介绍如何创建类的方法以及类的特殊方法,即构造方法和main()方法。
JAVA从入门到实践
4.3.1 定义类的成员方法
成员方法描述对象所具有的功能或操作,反映对象的行为,是具有某种相对独立功能的程序模块。它与过去所说的子程序、函数等概念相当。一个类或对象可以有多个成员方法,对象通过执行它的成员方法对传来的消息作出响应,完成特定的功能。成员方法一旦被定义,便可在不同的程序段中多次调用,故可增强程序结构的清晰度,提高编程效率。
1.成员方法的返回值
2.形式参数与实际参数
3.方法体中的局部变量
JAVA从入门到实践
4.3.2 构造方法
Java中的每个类都有构造方法,它是类的一种特殊的方法。构造方法用来初始化类的一个新的对象。它必须具有和类名相同的名称,而且不指出返回类型,它的默认返回类型就是对象类型本身。每个类可以具有多个构造方法,它们各自包含不同的方法参数。构造方法的语法如下所示。
{public} {abstract|final} class {extends } {implements } {
Classname({paramList}); //定义构造方法
Classname({paramList}); //定义其他构造方法
…
//类主体
}
其中,类声明部分的参数在前面已经介绍。最大的特点是存在一到多个与类同名的方法,这些方法就是构造方法。
JAVA从入门到实践
4.3.3 main()方法
main()方法是Java程序执行的入口。作为application执行的Java程序,有且只能有一个类具有main()方法。main()方法定义的语法如下所示。
public static void main(String args[]) {
//方法体
}
其中,访问控制权限是公有的(public),并且是类的静态成员方法(static),没有返回值(void)。这些特性对main()方法来说是指定的且不能改变的。main()方法具有一个字符串数组参数,用来接收执行Java程序时的命令行参数。命令行参数作为字符串,按照顺序依次对应字符串数组中的元素。
JAVA从入门到实践
4.3.4 方法的可变参数
以上几节介绍了类中方法的创建。在具体实际开发过程中,有时方法中参数的个数是不确定的。为了解决这个问题,在J2SE 5.0 版本中引入了可变参数的概念。声明可变参数的语法格式如下所示。
methodName ({paramList},paramType…paramName)
其中,参数methodName表示方法名称。参数paramList表示方法的固定参数列表。参数paramType表示可变参数的类型。参数…是声明可变参数的标识。参数paramName表示可变参数名称。可变参数必须定义在参数列表的最后。
JAVA从入门到实践
4.4 关键字this
在示例4-4中,出现了Java关键字this。this是Java语言中一个特殊的关键字,用来代表当前对象。关键字this是与对象密切相关的,在容易混淆的地方使用this会使程序设计变得规范、简单、灵活。
JAVA从入门到实践
4.5 对象
对象是对类的实例化。对象具有状态和行为,变量用来表明对象的状态,方法表明对象所具有的行为。Java对象的生命周期包括创建、使用和清除。本节详细介绍对象的整个声明周期过程。
JAVA从入门到实践
4.5.1 对象的创建
要使用一个对象,首先要创建它。通常创建对象的语法如下所示。
type objectNmae = new type({paramList});
其中,参数type表示对象的类型。参数objectName表示对象的名称。参数new为Java的关键字,下面会详细介绍。参数type({paramList})是对类型type构造方法的调用。
JAVA从入门到实践
4.5.2 对象的使用
对象定义好了之后,才可以使用对象。对象的使用即是调用对象的变量或方法。使用对象的语法如下所示。
objectNmae.memberVariableName //调用对象的变量
objectNmae.memberMethodName //调用对象的方法
其中,参数objectNmae表示对象的名称。参数memberVariableName表示对象的成员变量名称。参数memberMethodName表示对象的成员方法名称。
JAVA从入门到实践
4.5.3 对象的清除
对象使用完之后需要进行对象的清除。对象的清除是指释放对象占用的内存。在创建对象时,用户必须使用new操作符为对象分配内存。不过,在清除对象时,由系统自动进行内存回收,不需要用户额外处理。这也是Java语言的一大特色,某种程度上方便了程序员对内存的管理。
Java语言的内存自动回收称为垃圾回收(Garbage Collection)机制,简称GC。垃圾回收机制是指JVM用于释放那些不再使用的对象所占用的内存。Java语言并不要求JVM有GC,也没有规定GC如何工作。不过常用的JVM都有GC,而且大多数GC都使用类似的算法管理内存和执行收集操作。具体的垃圾收集实现策略有好多种,在此不再详细赘述。
JAVA从入门到实践
4.6 本章实例
在开发某图书管理系统时,其中有三个类,即图书类Book、图书类别类BookType和图书管理类BookManager。图书类Book用于管理图书本身的相关信息,包括编号、书名、作者、出版社等;图书类别类BookType用于表示图书分类,包括类别编号、类别名称等;图书管理类BookManager用于管理所有图书,主要是针对数据库进行操作,包括增加、删除、修改等。下面是这几个类的类图及源代码。
JAVA从入门到实践
4.7 上机实践
1.编写程序,创建一个汽车类(Car)。该类包含颜色和型号属性,并为其创建两个构造函数:
第一个为无形参的构造函数,其过程是将颜色和型号初始化为红色轿车。
第二个须定义两个形参,并将形参的值分别赋给颜色和型号。
另外,为该类创建两个方法,分别用来获得颜色和型号。在该类中定义一个main()方法,分别用上面的两个构造函数创建两个对象,并显示相关对象的各个属性。
汽车类(Car)类图如图4-8所示。
JAVA从入门到实践
4.8 小结
本章介绍了Java语言面向对象编程中有关类与对象的相关知识。主要包括类及成员变量、成员方法的创建,以及对象的创建、使用、清除等方面的知识。本章最后给出了一个完整的实例。其中类的成员变量、成员方法的定义和使用是本章的难点。在实际编程过程中,应该多通过具体实例加深理解。下一章徊缴钊虢樯Java语言面向对象编程方面的知识,包括类的继承、封装、多态以及接口和包等。
JAVA从入门到实践
4.9 本章习题
1.定义一个类,包含成员变量、构造方法、成员方法。
2.构造方法与成员方法有哪些不同?
3.类和对象之间是什么关系,用具体实例说明如何创建一个类的对象。
JAVA从入门到实践
第5章 深入面向对象编程
除了基本的类和对象,Java语言的面向对象编程还包括抽象类、接口、内部类、包等高级特性。通过对这些高级特性的支持,Java语言全面实现了面向对象的编程。下面进一步深入介绍Java语言面向对象编程方面的知识。本章包括以下知识点。
类的封装、继承、多态;
抽象类与接口;
内部类及匿名内部类;
包的创建及使用。
JAVA从入门到实践
5.1 类的封装、继承与多态
上一章介绍了有关类定义的基本知识。面向对象中的类还具有封装、继承与多态的特性,这也是面向对象编程所具有的重要特点。Java语言对类的封装、继承、多态均有很好的体现,下面分别进行介绍。
JAVA从入门到实践
5.1.1 封装
封装是指隐藏对象的属性及实现细节,对外仅提供接口可见。封装实现了信息隐藏,有利于软件复用。这种技术带来的好处是达到了模块化的标准,从而提高了代码的复用程度。在某种程度上,封装也大大改善了软件开发的可维护性,降低了构建复杂软件系统的风险。
在Java语言中,对象的属性和方法均可以进行访问控制。使用前面介绍的访问控制修饰符public、private、protected、default,可以实现不同程度的信息封装。下面通过一个具体的示例来介绍Java语言中封装的实现。
JAVA从入门到实践
5.1.2 继承
继承是指一个类是从另一个类派生而来,派生类自动具有了被继承类的所有特性。其中被继承的类称为“父类”,继承父类的类称为“子类”。继承可以使子类具有父类的各种属性和方法,而不需要再次编写相同的代码。继承也极大地促进了软件的复用,而且继承的形式可以更加复杂。Java语言中类继承的语法格式如下所示。
class ClassName extends SuperClassName {
//类体
}
其中,参数class是关键字。参数Classname表示类名,可以由用户任意定义,但需要符合Java标识符的命名规范。参数extends是关键字,表示该类继承自其他类。参数SuperClassName表示被继承的父类的名字,可以由用户任意定义,但需要符合Java标识符的命名规范。
JAVA从入门到实践
5.1.3 多态
多态是指对于一种服务功能,可以具有不同的实现方式,即多种形态。多态形象的描述了现实世界的复杂形态,使程序具有良好的扩展性。在继承的基础上,方法重载是实现多态的方式之一。
JAVA从入门到实践
5.2 抽象类与接口
抽象类是Java语言中一种特殊的类,其中包含只进行了声明没有具体实现的抽象方法。而接口更像是一种特殊的抽象类,其中所有方法都只进行了声明没有具体实现。抽象类和接口有着相似之处,不过也有许多区别。下面分别对它们进行详细地介绍。
JAVA从入门到实践
5.2.1 抽象类
抽象类是指包含了抽象方法的类。其中,抽象方法是一种只声明了方法名称,而没有指明方法体的方法。当需要表示对问题域进行分析、设计中得出的抽象概念时需要使用抽象类。抽象类比类的继承更高一层,是对类的抽象。抽象类拥有未实现的方法,不能被实例化,只能被继承扩展。Java语言中通常抽象类的语法格式如下所示。
abstract class ClassName {
abstract ReturnType abstractMethodName(paramList);
… //其他类成员
}
其中,参数abstract是关键字,表示此类为抽象类。参数class是关键字。参数Classname表示类名,可以由用户任意定义,但需要符合Java标识符的命名规范。类体中至少包含一个抽象方法。其中,参数abstract是关键字,表示此方法为抽象方法。参数ReturnType表示抽象方法的返回类型,为合法的Java数据类型。参数abstractMethodName表示抽象方法的名子,可以由用户任意定义,但需要符合Java标识符的命名规范。参数paramList表示抽象方法的参数列表。
JAVA从入门到实践
5.2.2 接口
接口是面向对象编程中又一重要概念。在实际问题中,有些互不相关的类具有某种相同的行为,这时可以采用接口来定义这种相同的行为。接口只定义提供什么功能,而不定义功能的具体实现,这一点与抽象类有些类似。在Java语言中,不提供类的多继承,一个子类只能继承自一个父类。为了解决多继承的问题,在Java中可以采用接口来实现。一个类虽然不能同时继承多个类,却可以同时实现多个接口,从而可以解决现实中的多继承问题。有关接口的知识包括接口定义、接口实现,下面分别进行介绍。
1.接口定义
2.实现接口
JAVA从入门到实践
5.3 内部类
内部类指的是在类的内部嵌套定义的类。内部类本身的结构同普通类没什么不同,只不过定义的位置是在另一个类的内部。定义的内部类同样可以在被外部引用。内部类可以只定义类体,没有名称,这就是匿名内部类。关于内部类的这些知识下面分别进行介绍。
JAVA从入门到实践
5.3.1 内部类
根据内部类的概念,内部类定义的位置是在类的内部。在一个类的任意代码块内,均可以进行内部类的定义。如可以直接作为类成员定义,可以定义在类的成员方法内、循环体内等。
JAVA从入门到实践
5.3.2 匿名内部类
匿名内部类是一种没有类名的特殊内部类。就像仅使用一次的变量可以不定义名称一样,匿名内部类也是用作定义仅使用一次的类。匿名内部类通常具有特殊的用途,也能使程序显得更加简洁。
JAVA从入门到实践
5.4 包
在面向对象编程中,包是Java语言所特有的概念。包用来将相关的一组类组织在一起进行管理,类似操作系统中的文件管理。包在外在形式上就是操作系统中的文件夹,包的内容就是类文件。不同的包可以包含同名的类,包机制有效解决了命名冲突问题。有关包的知识包括创建包和使用包,下面分别进行介绍。
JAVA从入门到实践
5.4.1 创建包
在使用包之前,首先需要创建包。创建包的语法格式如下所示。
package PackageName;
其中,参数package是关键字表示包。参数PackageName表示包名,可以由用户任意定义,但需要符合Java标识符的命名规范。
JAVA从入门到实践
5.4.2 使用包
创建了包之后,经常需要使用不同包中的类。使用不同包中的类主要具有两种形式:包名加类名形式、import导入形式。另外,在J2SE 5.0版本之后,还提供了静态导入功能。对这些内容,下面分别进行介绍。
1.包名加类名
2.import导入
3.静态导入
JAVA从入门到实践
5.5 本章实例
下面的实例采用面向对象的方法设计一个简单的学生管理系统。某高校在校的学生主要包括成人教育生、本科生、研究生这三类。每年新入学的学生要进行注册,毕业的学生要予以注销,三类学生注册、注销的方式可能略有不同。
经过对系统进行需求分析,识别出系统中主要包括成人教育学生类、本科生类、研究生类,另外还要包括学生管理类。由于本章实例主要为巩固面向对象方面的知识,所以系统中涉及到的对象持久化方面的内容这里进行省略。对系统进行面向对象设计,该系统主要包括如下两个包:
(1)entity包:用于包含实体类。
(2)business包:用于业务操作,这里只定义了一个StudentManager类。
JAVA从入门到实践
5.6 上机实践
1.编写程序,定义一个汽车类。它有两个子类,一个是卡车类,一个是轿车类。
2.编写程序,首先定义一个接口,在接口中声明计算面积的功能方法。然后定义两个类,一个为正方形类,一个为三角形类,分别实现接口中定义的计算面积方法。
JAVA从入门到实践
5.8 小结
本章进一步深入地介绍了Java语言中面向对象编程的相关知识,包括类的封装、继承、多态以及抽象类、接口、内部类、包等。本章最后给出了一个完整的实例。其中抽象类与接口的具体运用是本章的难点。抽象类与接口是面向对象编程中更加抽象的概念,要想能真正发挥它们的特点需要多结合具体需求反复实践。下一章将介绍Java语言中复合数据类型相关的内容,如数组、字符串、集合等。
JAVA从入门到实践
5.9 本章习题
1.举例说明如何实现类的继承与扩展。
2.抽象类与接口都有哪些区别?
3.包有什么作用?
JAVA从入门到实践
第6章 复合数据类型
除了简单数据类型外,Java语言还定义了许多复合数据类型,如数组、字符串、集合等。这些复合数据类型都是以类的形式进行定义的,包含许多属性和方法。综合使用简单数据类型和这些复合数据类型,可以处理实际需求中遇到的各种数据形式,能够编写更加复杂的程序。另外,自J2SE 5.0版本以来,Java语言又增加了许多新的特性,如增加的for循环、泛型、枚举等。本章包括以下知识点。
数组的定义、使用;
字符串的各种操作;
集合的各种知识;
增强的for循环及泛型、枚举、自动装箱与拆箱。
JAVA从入门到实践
6.1 数组
数组是Java语言中的一种复合数据类型,是具有相同数据类型的数据集合。数组中的每个数据称为数组元素,数组元素是有序的。关于数组的知识主要包括数组的定义、创建数组、数组的使用及多维数组,下面分别进行介绍。
JAVA从入门到实践
6.1.1 数组的定义
要使用数组,首先需要定义数组。定义数组的语法格式有两种,如下所示。
datatype[] arrayName;
或:
datatype arrayName[];
其中,参数datatype表示数据类型,可以是Java语言中的各种数据类型。参数arrayName表示数组名称,可以由用户任意定义,但需要符合Java标识符的命名规范。参数[]表示声明的为数组类型,可以放在数据类型后或数组名称后。
JAVA从入门到实践
6.1.2 创建数组
要想数组能被真正使用,只定义数组是不够的,还需要为数组分配内存空间完成和初始化。下面分别进行介绍。
1.创建数组
2.数组初始化
JAVA从入门到实践
6.1.3 数组的使用
数组创建完成后即可使用数组。数组的使用最普遍的就是访问数组的元素。访问数组元素的语法格式如下所示。
arrayName[subscript]
其中,参数arrayName表示数组名称,可以由用户任意定义,但需要符合Java标识符的命名规范。参数subscript表示数组下标,下标从0开始,到数组长度减1结束。另外,可以通过数组的length属性访问数组的长度。关于属性的概念后续章节会详细说明。
JAVA从入门到实践
6.1.4 多维数组
由于数组的数据类型可以是各种Java数据类型,当然也包括数组。这种数组类型的数组就构成了多维数组。比如二维数组是一个数组元素为数组的一维数组。如此递归,可以形成更多维数组。下面以二维数组为例进行讲解,多维的情形与二维类似。
二维数组的定义、创建、初始化与一维数组类似。语法格式如下所示:
datatype[][] arrayName; //二维数组的定义
arrayName = new datatype[][]; //二维数组的创建
arrayName[subscript] [subscript] //二维数组的使用
其中,参数意义与一维数组中的一致,这里不再赘述。
JAVA从入门到实践
6.2 字符串
字符串是Java中经常使用的复合数据类型。在本质上,字符数实际上为char型数组。字符串由Java.lang.String类来表示,该类具有一系列的属性和方法,提供对字符串的各种操作。除了String类,Java还提供了StringBuffer类用来处理可变长度的字符串。下面分别进行介绍。
JAVA从入门到实践
6.2.1 创建字符串
同其他类型数据一样,要想使用字符串数据,首先需要创建字符串。创建字符串的语法格式如下所示。
String variableName = new String();
其中,参数String为关键字。参数variableName表示字符串变量名称,可以由用户任意定义,但需要符合Java标识符的命名规范。参数new为关键字。=号右边表示为字符串变量分配内存空间。
JAVA从入门到实践
6.2.2 字符串连接
字符串连接是程序中经常进行的操作,用来将多个字符串连接在一起形成一个字符串。字符串连接使用+加法运算符进行。在Java语言中,采用+运算符还可以直接连接字符串和基本数据类型中的数值类型。此时,+运算符是作为字符串连接操作处理,其他数值类型自动转换为字符串。
JAVA从入门到实践
6.2.3 字符串比较
在实际编程过程中,经常需要对两个字符串变量的内容进行比较。Java语言中的String类提供了几个方法分别适合不同情况的字符串比较,如表6-1。
方法名称 方法功能
equals() 比较两个字符串的内容是否相等,返回boolean值
equalsIgnoreCase() 忽略大小写,比较两个字符串的内容是否相等,返回boolean值
compareTo() 按词典顺序比较字符串,返回int值
JAVA从入门到实践
6.2.4 字符串其他常用操作
字符串String作为数组和类,本身提供了许多方法用来进行各种复杂操作。表6-2列出了字符串一些常用方法及简单说明。
方法名称 方法功能
length() 返回字符串的长度
toLowerCase() 将其中的英文字母转换为小写
toUpperCase() 将其中的英文字母转换为大写
charAt(int index) 返回指定索引处的字符
indexOf(String str) 返回指定字符串第一个找到的索引位置
substring(int beginIndex) 返回指定索引处到字符串末尾的子串
substring(int beginIndex, int endIndex) 返回指定索引范围的子串
JAVA从入门到实践
6.2.5 StringBuffer类
由于String对象的长度是不可改变的,如果使用String类进行频繁的字符串拼接操作,那么会产生很多的对象。针对此类性能问题,Java语言提供了另一个类StringBuffer类可以特别用来处理此类问题。StringBuffer类主要包含如下一些方法。StringBuffer类常用方法如表6-3所示。
方法名称 方法功能
length() 返回字符串序列的长度
insert() 在字符串中间插入(提供了参数不同的多个方法)
append() 在字符串末尾追加(提供了参数不同的多个方法)
setCharAt(int index, char ch) 设置指定索引位置为指定字符
toString() 返回字符串
JAVA从入门到实践
6.3 集合
集合是多个对象的容器,容器里聚集了一组对象。前面介绍了数组类型,数组类型是有相同数据类型的数据集合。如果需要将不同数据类型的多个对象组织在一起,就需要使用集合。在Java语言中,集合本身一个框架体系,包含各种集合类。下面分别进行介绍。
JAVA从入门到实践
6.3.1 集合框架
在Java语言中,各种集合类通过集合框架进行组织。集合框架包括各类集合接口、接口实现类、集合操作,通过继承关系形成自上而下的体系结构。集合框架的核心接口为Collection、List、Set和Map,其继承关系如图6-1所示。
JAVA从入门到实践
6.3.2 访问集合元素
对所有集合类最经常的操作就是访问集合中的元素。在Java语言中定义了迭代器Iterator接口用于访问集合中的元素。下面列出了Iterator接口中定义的方法,如表6-4所示。
方法名称 方法功能
hasNext() 在迭代器当前位置,是否还有下一个元素
next() 返回下个元素
remove() 删除迭代器最后返回的那个元素
JAVA从入门到实践
6.3.3 列表(List)
List提供了对象的有序存放,其中存放的对象允许重复。List接口的具体实现类主要有ArrayList和LinkedList。其中ArrayList以一种类似数组的形式存储对象,对象的随机访问速度较快。LinkedList实现机制是采用链表,适合于在链表中间需要频繁进行插入和删除对象的操作。在实际的编程过程中,可以根据具体需要进行相应选择。
JAVA从入门到实践
6.3.4 集合(Set)
Set中存放的对象不允许重复,没有顺序。Set接口的具体实现类有HashSet和TreeSet类。其中HashSet能快速定位一个元素,但是放到HashSet中的对象需要实现hashCode()方法。TreeSet将放入其中的元素按顺序存放,要求放入其中的对象是可排序的。
JAVA从入门到实践
6.3.5 映射(Map)
Map提供了一种“键-值”对映射的方式存放对象。其中键和值也都可以是对象。对于键对象来说,像Set一样,一个Map容器中的键对象不允许重复。这就保证了键的唯一性,可以根据键对象快速定位值对象。对于值对象来说,则没有唯一性的要求,可以将任意多个键都映射到一个值对象上。Map接口的具体实现类有HashMap和TreeMap。其中HashMap也用到了哈希码的算法,以便快速查找一个键。TreeMap则是对键按序存放,要求放入其中的对象是可排序的。
JAVA从入门到实践
6.4 增强for循环
在J2SE 5.0版本以后,Java语言为迭代集合和数组提供了增强的for循环。增强的for循环提供了一个简单、兼容的语法,采用for-each语句形式。增强for循环的语法格式如下所示。
for (type elementName : array | collection) {
…
}
其中,参数type表示数组或集合元素的数据类型。参数elementName表示元素名称,可以由用户任意定义,但需要符合Java标识符的命名规范。参数array表示要迭代的数组,而collection表示要迭代的集合,应该为两者之一。
JAVA从入门到实践
6.5 泛型
泛型是J2SE 5.0版本中引入的最大特性,使用泛型编写的程序具有更好的安全性和可读性。泛型的使用范围很广,可以应用于集合类、定义泛型类、泛型方法等,下面对泛型的使用进行详细介绍。
JAVA从入门到实践
6.5.1 泛型集合
泛型对集合类来说有着非常重要的作用。在集合中引入泛型,能够提供编译时的类型安全,并且从集合中取得元素后不必再强制转换,简化了程序代码。定义泛型集合的语法格式如下所示。
CollectionType< datatype > collectionName = new datatype CollectionType< datatype >();
其中,参数CollectionType表示集合类型,可以为任意List、Set、Map等集合类型。参数<>为泛型标识。参数datatype表示集合元素的数据类型,可以是Java语言中的各种数据类型。参数collectionName表示集合名称,可以由用户任意定义,但需要符合Java标识符的命名规范。
JAVA从入门到实践
6.5.2 定义泛型类
泛型类是指包含类型参数的类。在泛型类的内部,类型参数可以用作变量的类型或方法返回参数的类型。另外,一个泛型类可以包含多个类型参数。定义泛型类的语法格式如下所示。
class className< typeParamList >
其中,参数class为关键字。参数className表示类名称,可以由用户任意定义,但需要符合Java标识符的命名规范。参数<>为泛型标识。参数typeParamList表示类型参数列表,多个类型参数之间用逗号分隔。
JAVA从入门到实践
6.5.3 泛型方法
与泛型类类似,包含类型参数的方法即为泛型方法。同样,一个泛型方法也可以包含多个类型参数。定义泛型方法的语法格式如下所示。
< typeParamList > returnType functionName(ParamList);
其中,参数<>为泛型标识。参数typeParamList表示类型参数列表,多个类型参数之间用逗号分隔。参数returnType 表示方法返回类型。参数functionName表示方法名称,可以由用户任意定义,但需要符合Java标识符的命名规范。参数ParamLis表示方法参数列表。
JAVA从入门到实践
6.5.4 泛型通配符
泛型一个重要的特点是可以使用“?”作为通配符,以此来匹配任何数据类型。泛型通配符的格式如下所示。
>
其中,参数<>为泛型标识。参数?为泛型通配符。
JAVA从入门到实践
6.6 枚举
枚举也是从J2SE 5.0版本开始引入的新特性,可以说是继类、接口之后引入的一种全新的“类”。枚举主要用于表示一组具名的值的有限集合,Java专门引入了“enum”关键字来表示枚举。对于枚举的定义和使用,下面分别进行详细介绍。
JAVA从入门到实践
6.6.1 定义枚举
枚举的定义很简单,与类的定义很相似。定义枚举的语法格式如下所示。
Modifier enum enumName {
;
…
}
其中,参数Modifier表示枚举修饰符,与类的修饰符一样,可以是public、private等。参数enum为关键字。参数enumName表示枚举名称,可以由用户任意定义,但需要符合Java标识符的命名规范。参数enumInstanceList表示枚举实例列表,多个实例之间用逗号分隔。另外,枚举中也可以定义方法,形式同类方法一样。
JAVA从入门到实践
6.6.2 使用枚举
在Java语言中,所有枚举类都是java.lang.Enum的子类。Enum类提供了values()和valueOf()方法用来访问枚举值。
JAVA从入门到实践
6.6.3 枚举带来的变化
引入枚举类型以后,对于以前的一些处理方法采用枚举来实现变得更加方便。
(1)枚举可以用于表示一组具名的值的有限集合。在引入枚举之前,类似枚举的结构更多的是用类似“public static final int”的语句进行实现。对上述实例中的季节(Season),不使用枚举定义的代码如下所示。
(2)引入枚举类型之后,产生的另一个影响是switch语句。有了枚举以后,switch语句的类型不再只能是byte、char、short、int类的数值型,而是可以为枚举。枚举与switch语句的结合使用,使得程序变得更加简洁。
JAVA从入门到实践
6.7 自动装箱和拆箱
自动装箱和拆箱是J2SE 5.0版本以后引入的新特性,用于解决Java语言基本数据类型与包装数据类型之间的转换问题。下面首先介绍一下包装类型,然后再介绍装箱与拆箱。
JAVA从入门到实践
6.7.1 包装类型
对于第二章中介绍的基本数据类型boolean、char、byte、short、int等,Java语言都为其定义了相应的包装类型,如Boolean、Character、Byte、Short、Integer。包装类型即对象类型,采用面向对象方法对数据类型进行了封装。每种包装类型定义为一个类,包含了相应的属性和方法。
JAVA从入门到实践
6.7.2 装箱与拆箱
自动装箱与拆箱大大地方便了基本数据类型与包装类型之间的操作。自动装箱功能可以将基本数据类型打包为相应的包装类型;而自动拆箱功能可以将包装类型解包为相应的基本数据类型。其中,“打包”的概念即是将包装类型的对象实例作为一种“壳”,将基本数据类型包到该对象中;“解包”是对应的反向操作。下面是采用自动装箱和拆箱对上述实例进行改造后的代码。
JAVA从入门到实践
6.8 本章实例
栈是非常重要的一种数据结构,在递归、函数调用中经常使用。作为一种操作受限的线性结构,栈的特点是后进先出。栈只能在称为栈顶的一端进行元素的插入、删除操作,所以最后插入进栈的元素要最先出栈。栈的主要操作是入栈和出栈。入栈是指从栈顶向栈内插入元素,出栈是值从栈顶删除元素。下面的实例分别采用数组和LinkedList集合类两种方式实现了数据结构中的栈。
JAVA从入门到实践
6.9 上机实践
1.编写程序,打印二维int型数组中的最小值。
2.编写程序,统计一个给定字符串中大写字母、小写字母、数字、其他字符的个数。
3.编写程序,用枚举定义一个Color类,包含Red、Blue、Green等颜色值。
JAVA从入门到实践
6.10 小结
本章介绍了Java语言中数组、字符串、集合这三种复合数据类型及泛型、枚举等新特性。本章最后给出了一个完整的实例。其中,各种集合类型的具体运用是本章的难点。在编写程序解决现实问题时,常常需要综合运用各种数据类型,从而处理各种形式的数据。在学习过程中,读者可以多参考一些经典的案例,一些具体方法的使用可以查阅相关的JDK API文档。下一章将介绍Java语言中有关异常处理方面的知识。
JAVA从入门到实践
6.11 本章习题
1.用程序实现对数组a[1,15,13,29,23,76,98,56,35]中元素进行从大到小排序。
2.练习类String和StringBuffer中各种方法的使用。
3.集合中List、Set、Map各有哪些区别?
4.举例说明泛型在集合中的应用。
JAVA从入门到实践
第7章 异常
Java语言提供了异常机制来处理程序运行过程中可能发生的各种非正常事件。通过异常处理机制,大大提高了程序的健壮性。Java语言对各种异常进行了相关的分类,提供了处理异常的不同手段,下面会进行详细介绍。本章包括以下知识点。
异常的分类
异常捕获、抛出
自定义异常
JAVA从入门到实践
7.1 异常概述
异常是指在程序运行过程中出现的非正常事件。Java语言采用面向对象的方法提供了一套异常处理机制。程序运行过程中发生的所有异常都被封装成异常类,根据异常的不同特点,划分为不同的异常类型。Java语言的异常类通过继承关系形成一个层次关系,如图7-1所示。
JAVA从入门到实践
7.2 异常分类
Java程序中处理的异常主要包括运行时异常和可控异常。运行时异常是扩展了RuntimeException类的异常类,在编写程序时不需要特别处理,在程序执行时有可能发生。可控异常是编写程序时即可预见的异常,此类异常需要程序对其做出处理,或进行捕获处理,或抛出交由上一层代码处理。关于异常捕获和抛出的知识在下面章节会详细介绍。对这两类异常,下面分别进行举例说明。
JAVA从入门到实践
7.2.1 运行时异常
Java语言中系统定义的常见运行时异常还有ArithmeticException、ArrayStoreException、BufferOverflowException、BufferUnderflowException、ClassCastException、IndexOutOfBoundsException等。
JAVA从入门到实践
7.2.2 可控异常
可控异常要求程序代码中对异常有明确处理,或进行捕获处理,或抛出交由上一层代码处理。Java语言中系统定义的可控异常还有IOException、DataFormatException、NamingException等。
JAVA从入门到实践
7.3 Java异常处理
对于程序中可能发生的各种异常,往往需要对其进行相关的处理,从而增加程序的健壮性。在Java语言中,对异常的处理包括捕获异常、向外抛出异常。另外,用户还可以定义自己的异常类,对异常信息进行重新包装。对于这些内容,下面分别进行介绍。
JAVA从入门到实践
7.3.1 捕获异常
对于程序中出现的异常,可以利用try…catch语句进行捕获。在编写程序过程中,有些操作无论是否发生异常,都应该进行处理(如关闭数据库连接),这样的处理代码可以放在finally代码块中。下面对try…catch语句和finally语句分别进行讲解。
1.try…catch语句
2.finally语句
JAVA从入门到实践
7.3.2 抛出异常
对于方法中可能出现的异常,如果不想在方法中进行捕获,可以在声明时利用throws语句进行抛出。在方法体中,可以使用throw语句抛出继承了throwable类的子类。抛出的异常由上一层代码进行处理。下面对throws语句和throw语句分别进行讲解。
1.throws语句
2.throw语句
JAVA从入门到实践
7.3.3 自定义异常
尽管Java语言定义了许多异常类,用户仍可以通过继承Exception类或RuntimeException类来自定义异常。自定义异常的语法格式如下所示。
class ExceptionName extends Exception {
//类体
}
其中,参数class为关键字。参数ExceptionName为自定义异常名称。参数extends为关键字。参数Exception为继承的父类。
另外可以通过继承RuntimeException类来自定义运行时异常,语法格式如下所示。
class ExceptionName extends RuntimeException {
//类体
}
其中各个参数同上述格式类似,这里不再赘述。只不过继承的父类为RuntimeException。
JAVA从入门到实践
7.4 本章实例
在实际开发的管理信息系统中,系统登录时经常需要连接数据验证账号、密码是否正确,然后决定是否有权使用系统。账号、密码验证看似是个很简单的操作,但从软件健壮性、可靠性方面考虑,却可能出现数据库操作异常、账号不存在、密码错误等问题。利用Java的异常处理机制,建立一个有效的系统异常处理框架是系统健壮性的有力保障。下面就已系统登录验证为例,建立了一个简单的异常处理框架,类图如图7-2所示。
JAVA从入门到实践
7.5 上机实践
1.编写程序,程序中包含异常处理语句try…catch、finally。
2.编写程序,自定义两种类型异常,一种为运行时异常,另一种为可控异常。
JAVA从入门到实践
7.6 小结
本章介绍了Java语言中的异常处理机制,包括异常的分类、捕获异常、抛出异常及自定义异常等知识。本章最后给出了一个完整的实例。其中,异常的捕获和抛出本章的难点和重点,也是实际编程过程经常需要进行的操作。下一章将介绍Java语言中有关多线程编程方面的内容。
(源码网整理:www.codepub.com)
JAVA从入门到实践
7.7 本章习题
1.异常都有哪些类型?举几个可控异常的例子,至少为三个。
2.举例说明如何捕获异常。
3.throw和throws有什么区别?
JAVA从入门到实践
第8章 线程
多线程编程是提高应用程序性能的重要手段之一。Java平台从开始就被设计成为多线程环境,从语言级上支持多线程。在Java语言中,提供了创建、启动、调度、同步等的各种线程管理方法,下面会进行详细介绍。本章包括以下知识点。
线程的基本概念;
创建与启动线程;
线程的生命周期;
线程调度;
线程同步。
JAVA从入门到实践
8.1 线程基本概念
随着计算机技术的迅猛发展,编程模型越来越复杂多样化。其中,多线程编程是提高应用程序性能的重要手段之一。多线程编程的目的是最大限度地利用CPU资源。当某一线程的处理不需要占用CPU而只和I/O、内存等资源打交道时,让需要占用CPU资源的其他线程有机会获得CPU资源。要掌握多线程编程,需要弄清如下两个区别。
1.进程与线程的区别
2.线程对象和线程的区别
JAVA从入门到实践
8.2 线程的创建与启动
要想执行一个线程,首先需要进行创建和启动。线程的创建完成线程的定义,实现了线程执行时所需完成的功能;线程的启动是对实例化的线程进行启动,使其获得执行的机会。对这两部分内容,下面分别进行介绍。
JAVA从入门到实践
8.2.1 创建线程
要使用线程,首先需要创建线程。在Java语言中,创建线程有两种方式,可以继承java.lang.Thread类或者实现Runnable接口。下面对这两种创建方式分别进行介绍。
1.继承Thread类
2.实现Runnable接口
JAVA从入门到实践
8.2.2 启动线程
线程创建完成后,通过线程的启动来执行线程。类Thread定义了start方法用来完成线程的启动。,针对两种不同的线程创建方式,下面分别介绍其启动方法。
1.继承Thread类方式线程的启动
2.实现Runnable接口线程的启动
JAVA从入门到实践
8.3 线程的生命周期
线程从其创建到死亡具有一个完整的生命周期,在整个生命周期中处于各种状态。线程的状态表明线程当前可以进行的活动。一个生命周期内的线程主要包括创建、就绪、运行、阻塞、死亡状态,如图8-1所示。
1.创建
2.就绪
3.运行
4.阻塞
5.死亡
JAVA从入门到实践
8.4 线程的调度
处于生命周期中的线程,通过调度实现各种状态间的转换。线程的调度是使用各种线程调度方法,如setPriority()、sleep()、yield()、join()等,对线程进行不同的操作。对于各种线程调度方法,下面分别进行介绍。
JAVA从入门到实践
8.4.1 线程优先级
线程优先级是指线程在被系统调度执行时的优先执行级别。在多线程程序中,往往是多个线程同时等待被调度执行。然而,每个线程的重要程度通常是不一样的,在同等条件下,有些重要线程需要优先执行。在Java语言中,通过调用setPriority()方法为线程设置优先级。优先级用1~10的数字表示,数字越大,优先级越高。
JAVA从入门到实践
8.4.2 线程休眠sleep()
对于正在执行的线程,可以调用sleep方法使其放弃CPU进行休眠,此线程转为阻塞状态。sleep方法包含long型的参数,用于指定线程休眠的时间,单位为毫秒。sleep方法还会抛出可控异常InterruptedException,程序需要对此异常进行处理。下面通过示例讲述sleep方法的使用。
JAVA从入门到实践
8.4.3 线程让步yield()
对于正在执行的线程,可以调用yield方法使其重新排队,将CPU让给排在后面的线程,此线程转为就绪态。另外,yield方法只让步给高优先级或同等优先级的线程,如果后面是低优先级线程,则继续执行此线程。yield方法没有参数,也没有声明抛出任何异常。下面通过示例讲述yield方法的使用。
JAVA从入门到实践
8.4.4 线程等待join()
对于正在执行的线程,可以调用join方法等待其结束,然后才执行其他程序。join方法有几种重载形式。其中,不带任何参数是等到执行结束为止,其他重载形式可参考JDK API。join方法也会抛出可控异常InterruptedException,程序需要对此异常进行处理。下面通过示例讲述join方法的使用。
JAVA从入门到实践
8.5 线程同步
当多个线程操作同一个共享资源时,比如读写同一个变量,存在着资源竞争的问题。为了解决此类问题,需要使用同步机制。在Java语言中,利用synchronized关键字实现线程同步。下面通过示例讲述线程的同步。
JAVA从入门到实践
8.6 本章实例
生产者/消费者问题是操作系统知识中的经典问题。生产者通常是指提供资源的进程(或线程),而消费者是消耗资源的进程(或线程)。大多情况下,生产者和消费者的数目都多于一个。本章实例即是通过Java语言中的多线程来实现生产者/消费者问题。实例实现中生产者、消费者均为线程。生产者线程向共享缓冲区中存放数据,消费者线程从共享缓冲区取数据。该实例的类图如图8-2所示。
JAVA从入门到实践
8.7 上机实践
1.编写程序,用两种方式创建并启动线程。
2.编写程序,使用各种调度方法控制线程运行状态。
JAVA从入门到实践
8.8 小结
本章介绍了Java语言中的多线程编程,包括创建与启动线程、线程的生命周期、线程调度、线程同步等知识。本章最后给出了一个完整的实例。其中各种线程调度方法是本章的难点。多线程编程属于程序语言编程中的高级知识,多学习一些操作系统相关方面的理论知识能够更好的掌握多线程编程。下一章将介绍Java语言中输入输出流方面的知识。
JAVA从入门到实践
8.9 本章习题
1.如何创建线程?用两种方式实现线程创建。
2.线程在生命周期中都有哪些状态?它们之间如何转换?
3.都有哪些线程调度方法?各有什么功能?
4.举例说明如何实现线程同步?
JAVA从入门到实践
第9章 Java的输入输出流
对于任何编程语言,处理数据的输入、输出操作都占有极其重要的地位。Java语言以流的形式进行数据的输入、输出处理。按照操作类型,Java语言中的流分为字节输入流、字节输出流、字符输入流、字符输出流,本章针对这些知识逐一详细介绍。本章包括以下知识点。
字节输入流
字节输出流
字符输入流
字符输出流
File类和RandomAccessFile类
JAVA从入门到实践
9.1 输入输出流概述
对于任何编程语言,处理数据的输入、输出操作都占有极其重要的地位。程序从数据源(包括各种输入设备,如键盘、磁盘、文件等)中读取数据称之为输入;程序将数据写入目标设备(包括各种输出设备,如显示器、磁盘、文件等)称之为输出。
在Java语言中,以流的形式进行数据的输入、输出。根据操作类型,把流分为输入流和输出流。数据从数据源经输入流读取到Java程序,处理后,又经输出流写入到目标设备,如图9-1所示。
JAVA从入门到实践
9.2 字节输入流
字节输入流用于以二进制的形式从数据源中读取数据。InputStream类是字节输入流的基类,该类包括FileInputStream、FilterInputStream、 BufferedInputStream、DataInputStream等子类。下面对这些内容进行详细介绍。
JAVA从入门到实践
9.2.1 字节输入流InputStream
InputStream是Java语言中字节输入流所有类的父类,该类是抽象类,不能被实例化。InputStream类中定义了许多与读取字节数据有关的方法,如下所示。
available():返回可以从输入流中读取的字节数。
close():关闭输入流。
mark():在输入流中标记当前位置。
markSupported():测试输入流是否支持mark()和reset()方法。
read():从输入流读取下一字节数据。
read(byte[] b):从输入流读取若干字节数据,并存储到字节数组。
read(byte[] b, int off, int len):从输入流读取至多len个字节数据,并存储到字节数组。
reset():将输入流重新定位到mark()方法标记的位置。
skip(long n):跳过输入流中n个字节数据。
JAVA从入门到实践
9.2.2 字节文件输入流FileInputStream
FileInputStream类用于以字节流的形式读取文件,它有如下三个构造方法。
FileInputStream(File file):通过file对象创建FileInputStream。
FileInputStream(FileDescriptor fdObj):参数fdObj为文件描述符,通过文件描述符创建FileInputStream。
FileInputStream(String name):参数name为文件路径名,通过文件路径创建FileInputStream。
JAVA从入门到实践
9.2.3 输入流过滤器FilterInputStream
FilterInputStream类称为过滤流输入类,用于扩展InputStream类,提供了许多增强的功能方法。FilterInputStream类的层次结构如图9-4所示。
JAVA从入门到实践
9.2.4 字节缓冲区输入流BufferedInputStream
BufferedInputStream类是InputStream类的间接子类,其直接父类是FilterInputStream。该类采用缓冲区机制进行字节流输入,支持mark()和reset()方法。BufferedInputStream类有如下两个构造方法。
BufferedInputStream(InputStream in):以InputStream对象in为参数创建BufferedInputStream。
BufferedInputStream(InputStream in, int size):以InputStream对象in为参数创建BufferedInputStream,并且通过参数size指定缓存区的大小。
JAVA从入门到实践
9.2.5 数据输入流DataInputStream
DataInputStream类用于读取Java语言中的基本类型数据,如byte、int、float、boolean等。该类定义了许多以read开头后面跟数据类型的方法,这些方法用于读取指定数据类型的数据,如下所示。
readBoolean():读取1个字节数据,并转换为boolean类型。
readByte():读取1个字节数据,并转换为byte类型。
readChar():读取1个字节数据,并转换为car类型。
readDouble():读取8个字节数据,并转换为double类型。
readFloat():读取4个字节数据,并转换为float类型。
readInt():读取4个字节数据,并转换为int类型。
JAVA从入门到实践
9.3 字节输出流
字节输出流用于以二进制的形式将数据写入目标设备。OutputStream类是字节输出流的基类,该类包括FileOutputStream、FilterOutputStream、 BufferedOutputStream、DataOutputStream、PrintStream等子类。下面对这些内容进行详细介绍。
JAVA从入门到实践
9.3.1 字节输出流OutputStream
OutputStream是字节输出流所有类的父类,该类是抽象类,不能被实例化。OutputStream类中定义了许多与写字节数据有关的方法,如下所示。
close():关闭输出流。
flush():刷新输出流,强制将缓冲区内容写入输出流。
write(byte[] b):将指定字节数组的内容写入输出流。
write (byte[] b, int off, int len) :将指定字节数组从off位置开始的len个字节写入输出流。
write(int b):将指定的字节写入输出流。
JAVA从入门到实践
9.3.2 字节文件输出流FileOutputStream
FileOutputStream类用于将字节流数据写入文件,它有如下五个构造方法。
FileOutputStream(File file):通过file对象创建FileOutputStream。
FileOutputStream(File file, boolean append):通过file对象创建FileOutputStream,append为true或false表示是否在文件末尾追加。
FileOutputStream(FileDescriptor fdObj):参数fdObj为文件描述符,通过文件描述符创建FileOutputStream。
FileOutputStream(String name):参数name为文件路径名,通过文件路径创建FileOutputStream。
FileOutputStream(String name, boolean append):参数name为文件路径名,通过文件路径创建FileOutputStream,append为true或false表示是否在文件末尾追加。
JAVA从入门到实践
9.3.3 输出流过滤器FilterOutputStream
FilterOutputStream类称为过滤流输出类,用于扩展OutputStream类,提供了许多增强的功能方法。FilterOutputStream类的层次结构如图9-6所示。
JAVA从入门到实践
9.3.4 字节缓冲区输出流BufferedOutputStream
BufferedOutputStream类是OutputStream类的间接子类,其直接父类是FilterOutputStream。该类采用缓冲区机制进行字节流输出,有如下两个构造方法。
BufferedOutputStream(OutputStream out):以OutputStream对象out为参数创建BufferedOutputStream。
BufferedOutputStream(OutputStream out, int size):以OutputStream对象out为参数创建BufferedOutputStream,并且通过参数size指定缓存区的大小。
JAVA从入门到实践
9.3.5 数据输出流DataOutputStream
DataOutputStream类用于将Java语言中的基本类型数据写入输出流,如byte、int、float、boolean等类型。该类定义了许多以write开头后面跟数据类型的方法,这些方法用于将指定数据类型的数据写入输出流,如下所示。
writeBoolean():写boolean类型数据。
writeByte():写 byte类型数据。
writeChar():写char类型数据。
writeDouble():写double类型数据。
writeFloat():写float类型数据。
writeInt():写int类型数据。
JAVA从入门到实践
9.3.6 字节打印流PrintStream
PrintStream类用于将字节数据进行格式化的输出。前面介绍的其他OutputStream类的子类在输出时均是保持原有字节数据的格式。而PrintStream类在输出时会进行字符格式转换,默认使用操作系统的编码进行字符转换。该类定义了许多print方法用于输出不同类型的数据,同时每个print方法又定义了相应的println方法,用于输出带换行符的数据。
JAVA从入门到实践
9.4 字符输入流
字符输入流用于以字符的形式从数据源中读取数据。Reader类是字符输入流的基类,该类包括FileReader、BufferedReader等子类。下面对这些内容进行详细介绍。
JAVA从入门到实践
9.4.1 字符输入流Reader
Reader是Java语言中字符输入流所有类的父类,该类是抽象类,不能被实例化。Reader类中定义了许多与读取字符数据有关的方法,如表9-1所示。
方法定义 方法功能
abstract void close() 关闭输入流
void mark () 在输入流中标记当前位置
boolean markSupported () 测试输入流是否支持mark()和reset()方法
int read () 从输入流读取下一字符
int read (char[] cbuf) 从输入流读取若干字符数据,并存储到字符数组
abstract int read (char[] cbuf, int off, int len) 从输入流读取至多len个字符数据,并存储到字符数组
boolean void ready () 判断是否准备读取输入流
void reset () 将输入流重新定位到mark()方法标记的位置
long skip (long n) 跳过输入流中n个字符数据
JAVA从入门到实践
9.4.2 字符文件输入流FileReader
FileReader类用于从文件中读取字符数据,它有如下三个构造方法。
FileReader(File file):通过file对象创建FileReader。
FileReader(FileDescriptor fd):参数fd为文件描述符,通过文件描述符创建FileReader。
FileReader(String name):参数name为文件路径名,通过文件路径创建FileReader。
JAVA从入门到实践
9.4.3 字符缓冲区输入流BufferedReader
BufferedReader类采用缓冲区机制进行字符流输入,支持mark()和reset()方法。BufferedReader类有如下两个构造方法。
BufferedReader(Reader in):以Reader对象in为参数创建BufferedReader。
BufferedReader(Reader in, int sz):以Reader对象in为参数创建BufferedReader,并且通过参数sz指定缓冲区的大小。
JAVA从入门到实践
9.5 字符输出流
字符输出流用于以字符的形式将数据写入目标设备。Writer类是字符输出流的基类,该类包括FileWriter、BufferedWriter、PrintWriter等子类。下面对这些内容进行详细介绍。
JAVA从入门到实践
9.5.1 字符输出流Writer
Writer类是字符输出流所有类的父类,该类是抽象类,不能被实例化。Writer类中定义了许多与写字符数据有关的方法,如表9-2所示。
方法定义 方法功能
abstract void close() 关闭输出流
abstract void flush() 刷新输出流,强制将缓冲区内容写入输出流
void write (char[] cbuf) 将指定字符数组的内容写入输出流
abstract void write (char[] cbuf, int off, int len) 将指定字符数组从off位置开始的len个字符写入输出流
write(int c) 将指定的字符写入输出流
write(String str) 将指定的字符串写入输出流
write(String str, int off, int len) 将指定字符串从off位置开始的len个字符写入输出流
JAVA从入门到实践
9.5.2 字符文件输出流FileWriter
FileWriter类用于将字符数据写入文件,它有如下五个构造方法。
FileWriter(File file):通过file对象创建FileWriter。
FileWriter(File file, boolean append):通过file对象创建FileWriter,append为true或false表示是否在文件末尾追加。
FileWriter(FileDescriptor fd):参数fd为文件描述符,通过文件描述符创建FileWriter。
FileWriter(String fileName):参数fileName为文件路径名,通过文件路径创建FileWriter。
FileWriter(String fileName, boolean append):参数fileName为文件路径名,通过文件路径创建FileWriter,append为true或false表示是否在文件末尾追加。
JAVA从入门到实践
9.5.3 字符缓冲区输出流BufferedWriter
BufferedWriter类采用缓冲区机制进行字符流输出,有如下两个构造方法。
BufferedWriter(Writer out):以Writer对象out为参数创建BufferedWriter。
BufferedWriter(Writer out, int sz):以Writer对象out为参数创建BufferedWriter,并且通过参数sz指定缓存区的大小。
JAVA从入门到实践
9.5.4 字符打印流PrintWriter
PrintWriter类同用于将字符数据进行格式化的输出。前面介绍的其他Writer类的子类在输出时均是保持原有字符数据的格式。而PrintWriter类在输出时会进行字符格式转换,默认使用操作系统的编码进行字符转换。该类定义了许多print方法用于输出不同类型的数据,同时每个print方法又定义了相应的println方法,用于输出带换行符的数据。
JAVA从入门到实践
9.6 文件
输入、输出操作经常处理的设备之一是文件。Java语言提供了File类和RandomAccessFile类来对文件进行处理。File类用于管理文件系统中的文件或目录,RandomAccessFile类提供了随机读写文件的功能。下面对这些内容进行详细介绍。
JAVA从入门到实践
9.6.1 File类
File类用于管理文件系统中的文件或目录。该类定义了许多方法可以对文件或目录进行各种操作,如创建、查看、删除文件或目录等。目录其实是作为一种特殊的文件进行处理,File类专门定义了与目录管理有关的方法。
JAVA从入门到实践
9.6.2 RandomAccessFile类
RandomAccessFile类用于随机的读写文件。前面介绍的字节输入/输出流(InputStream/OutputStream)、字符输入/输出流(Reader/Writer)当处理文件时,都只能按照顺序进行读或写。RandomAccessFile类可以在任意位置进行读写操作,处理文件更加灵活。RandomAccessFile类定义的与读写位置有关的主要方法如下所示。
getFilePointer():获得文件读写指针所在的位置。
length():获得文件长度。
seek(long pos):设置文件读写指针到第pos个字节处。
skipBytes(int n):使读写指针跳过n个字节。
JAVA从入门到实践
9.7 本章实例
在操作系统的使用过程中,复制文件是经常进行的操作。下面的实例利用本章所讲的知识实现了文件复制功能。该实例支持从一个文件复制到另一个文件,但不支持目录复制。在复制过程中,包含必要的错误检查,如源文件不可读、目标文件已存在等。该实例的类图如图9-9所示。
JAVA从入门到实践
9.8 上机实践
1.编写程序,读入一个文本文件,将其内容隔行打印。
2.编写程序,从标准输入设备上接收字符并打印。
JAVA从入门到实践
9.9 小结
本章介绍了Java语言中的各种输入、输出流,包括字节输入流、字节输出流、字符输入流、字符输出流,还介绍了用于文件操作的File类和RandomAccessFile类。本章最后给出了一个完整的实例。其中,各种常用的输入、输出流类的使用是本章的难点。下一章将介绍Java语言中图形界面开发的相关知识。
JAVA从入门到实践
9.10 本章习题
1.字节流和字符流主要有什么区别?
2.练习使用FielInputStream和FielOutputStream类。
3.文件操作主要有哪两种方式?
JAVA从入门到实践
第10章 图形用户界面
图形用户界面(Graphical User Interface)简称GUI,提供了一种更加直观、友好的与用户进行交互的方式。Java语言进行图形用户界面操作主要由java.awt和javax.swing两个包来完成。其中,AWT包是图形用户界面处理的基本工具包,Swing包在AWT包的基础上进行了升级、扩展,具有更加强大的图形界面开发功能。本章包括以下知识点。
AWT简介
AWT包关于容器、布局管理器、事件处理、基本组件的知识
Swing简介
Applet知识
JAVA从入门到实践
10.1 AWT简介
AWT是抽象窗口工具箱的简称,包括了图形界面编程的基本类库。其作为Java语言GUI程序设计的核心,作用是给用户提供基本的界面构件。这些构件可以用来建立图形用户界面的独立平台,从而使得用户和机器之间更好的进行交互。AWT包的内容主要分为四部分:
容器:用于放置基本组件,本身也是一种组件。
布局管理器:对容器中放置的组件进行布局管理。
事件处理:采用事件处理机制,使得用户能够通过图形界面与系统进行交互。
基本组件:包括按钮、标签、文本域等,是图形界面的基本组成元素。
JAVA从入门到实践
10.2 容器
容器是用来存放其他组件的一种特殊组件。在Java语言中,所有容器类都是Container类的子类。Container类继承了Component类,该类的两个常用子类是Frame和Panel类。Frame和Panel类代表两种不同类型的容器,下面分别进行介绍。
JAVA从入门到实践
10.2.1 Frame 类
Frame类容器是一种带有边框的框架窗口,可以不依赖于其他组件独立存在。Frame类继承了Window类,可以带标题、设置大小等。Frame类中定义了许多操作容器的方法。
JAVA从入门到实践
10.2.2 Panel 类
Panel类容器没有任何边框,而且需要存在于其他容器中。该类容器只是包含在其他容器中的一个区域,通常用来将许多组件组合在一个区域内。Panel类中定义的方法,如下所示。
Panel():构造方法,使用默认的布局管理器创建新面板。
Panel(LayoutManager layout):构造方法,创建具有指定布局管理器的新面板。
void addNotify():创建Panel的同位体。
AccessibleContext getAccessibleContext():获取与Panel相关的AccessibleContext。
JAVA从入门到实践
10.3 布局管理器
布局管理器用于布局容器中的组件,包括设定组件的位置和尺寸大小等。每个容器被创建后,都会有一个默认布局管理器。另外,可以设置指定的布局管理器对组件进行管理。Java语言的AWT包提供了不同类别的布局管理器,包括BorderLayout、FlowLayout、CardLayout等,下面分别进行介绍。
JAVA从入门到实践
10.3.1 BorderLayout管理器
BorderLayout布局管理器将容器划分为东(East)、西(West)、南(South)、北(North)、中(Center)五个区域。它是Frame类的默认布局管理器。采用BorderLayout布局时,向容器中添加组件需要指定组件所在的区域。BorderLayout类的构造方法主要有:
BorderLayout():使用默认的居中对齐方式,水平和垂直间距为默认值。
BorderLayout(int align):使用指定对齐方式,水平和垂直间距为默认值。
BorderLayout(int align, int hgap, int vgap):使用指定的对齐方式、指定水平间距、垂直间距。
JAVA从入门到实践
10.3.2 FlowLayout管理器
FlowLayout布局管理器用于将组件按照从左到右、从上到下的顺序进行布局。它是Panel类的默认布局管理器。采用FlowLayout布局,不会改变组件的大小,按组件原有尺寸显示。当一个组件在本行放不下时,将自动换到下一行。FlowLayout布局管理器组件间默认的间距是5个像素,默认对齐方式是居中。当然,可以调用相关方法设置不同的组件间距、行距以及对齐方式。FlowLayout类的构造方法主要有:
FlowLayout():使用默认的居中对齐方式,水平和垂直间距为默认值。
FlowLayout(int align):使用指定对齐方式,水平和垂直间距为默认值。
FlowLayout(int align, int hgap, int vgap):使用指定的对齐方式、指定水平间距、垂直间距。
JAVA从入门到实践
10.3.3 CardLayout管理器
CardLayout布局管理器用于将组件以卡片的形式进行布局。采用CardLayout布局,每张卡片属于不同的层次,并且充满整个容器。当往容器中添加组件时,需指定所在卡片的名字。CardLayout类的构造方法主要有:
CardLayout():无参构造方法。
CardLayout(int hgap, int vgap):以指定间距创建CardLayout布局管理器,hgap指定卡片与容器的水平间距,vgap指定卡片与容器的垂直间距。
JAVA从入门到实践
10.3.4 GridLayout管理器
GridLayout布局管理器将容器划分为由行和列组成的多个网格,每个网格放一个组件。采用GridLayout布局时,在容器中按照从左到右、从上到下的顺序往网格中逐个添加组件。GridLayout类的构造方法主要有:
GridLayout():无参构造方法。
GridLayout(int rows, int cols):使用指定行数和列数。
GridLayout(int rows, int cols, int hgap, int vgap):使用指定的行数和列数及水平间距、垂直间距。
JAVA从入门到实践
10.3.5 GridBagLayout管理器
GridBagLayout布局管理器在GridLayout布局管理器的基础上提供了更加复杂的功能。采用GridBagLayout布局时,一个组件可以跨越多个行列放在多个网格内。另外,可以通过设定填充方式、间距等任意调整组件的大小和位置。GridBagLayout布局管理器引入了GridBagConstraints类,该类用于辅助定义有关组件布局的各种属性。
JAVA从入门到实践
10.4 事件处理
事件处理是图形界面与用户进行交互的重要内容。Java语言的事件处理机制包括事件源、事件、事件处理器三个主要的概念。首先需要为事件源注册相应的事件处理器,事件源产生指定事件后,事件处理器捕获后进行相应事件处理。关于事件处理的具体内容,下面进行详细介绍。
JAVA从入门到实践
10.4.1 事件处理概述
事件处理是图形用户界面中的重要部分。应用程序生成的图形界面应该能够响应用户的各种操作,如鼠标单击、键盘键按下、单击按钮等。程序对用户操作的响应使得系统能够和用户进行各种交互,从而可以实现各种处理流程。图形界面对用户操作的响应采用事件处理的机制来完成,该机制包括三个重要的概念:
事件源:产生事件的各种组件,如窗口、按钮、复选框等。
事件:用户对事件源的各种操作动作。
事件处理器:用于接收并处理事件的方法。
JAVA从入门到实践
10.4.2 事件监听器
事件监听器是用于监听事件源触发事件的对象,其中包含对事件发生后的处理操作。在Java语言中,针对不同的事件,定义了相应的事件监听器接口。了解了事件监听器的基本概念后,下面介绍如何使用事件监听器。使用事件监听器进行事件处理的一般步骤为:
(1)定义监听器类,该类实现了相应的监听器接口。
(2)在事件源上调用类似addXxxxListener()方法注册上面定义的事件监听器。
(3)相应事件触发后,执行监听器中定义的相应处理方法,进行事件处理。
(4)调用类似removeXxxxListener()的方法注销监听器。
JAVA从入门到实践
10.4.3 事件适配器
上一节介绍的事件监听器通常都是以实现接口的方式进行定义的。因为实现接口就要实现其定义的所有方法,当仅为实现一个事件方法而采用事件监听器方式时所写的代码就显得非常复重。在Java语言中,针对每个事件监听器接口,系统定义了相应的实现类,称为事件适配器。只要继承事件适配器类,仅覆盖需要的相应方法就可以处理某个特定的事件了,这样代码变得更加简洁。
JAVA从入门到实践
10.5 AWT基本组件
基本组件是构成图形用户界面的基本元素。基本组件添加到容器中,由专门的布局管理器管理布局,通过事件机制来响应用户的操作。Java语言的AWT包提供了各种基本的图形界面组件,包括Button、Label、Checkbox等,下面分别进行介绍。
JAVA从入门到实践
10.5.1 按钮
按钮Button是图形界面中经常使用的组件,用户按下按钮时触发一定的执行动作。Button类的一些常用方法如下所示。
JAVA从入门到实践
10.5.2 标签
标签Label用于在图形界面上显示一行只读的文本。Label类的一些常用方法如下所示。
void addNotify():创建此标签的同位体。
AccessibleContext getAccessibleContext():获取与此标签相关的AccessibleContext。
int getAlignment():获取此标签的当前对齐方式。
String getText():获取此标签的文本。
protected String paramString():返回一个表示此Label状态的字符串。
void setAlignment(int alignment):将此标签的对齐方式设置为指定的方式。
void setText(String text):将此标签的文本设置为指定的文本。
JAVA从入门到实践
10.5.3 单行文本域
上面介绍的标签组件显示的文本是只读的,用户不能进行编辑。单行文本域TextField组件提供了单行文本编辑的功能。
JAVA从入门到实践
10.5.4 多行文本域
单行文本域TextField虽然能够让用户编辑文本,但只能在一行内编辑。当需要编辑多行的文本时,需要使用多行文本域组件TextArea。
JAVA从入门到实践
10.5.5 复选框和单选按钮
Checkbox组件属于一种选择按钮,用户可以进行相关选项的选择。结合CheckboxGroup类使用,Checkbox组件可以分别实现复选框和单选按钮的功能。如果不给多个Checkbox组件设置分组CheckboxGroup,则这些Checkbox组件是复选框,用户可以同时选中多个选项;如果给多个Checkbox组件设置为同一个分组CheckboxGroup,则这些Checkbox组件为单选按钮,每次只能有一个选项选中。
JAVA从入门到实践
10.5.6 列表
列表List组件用于列举多个可供选择的文本选项,包含单选和多选两种模式。列举的文本选项分为多行,只能进行选择,不能编辑。
JAVA从入门到实践
10.6 Swing简介
AWT包包括了进行图形界面开发的各方面内容,如容器、组件、布局管理、事件处理等。采用AWT包开发的图形界面一个主要特点是依赖于具体的操作系统,不同的操作系统,显示的图形外观可能不同。从JDK1.2版本以后,Java语言引入了一个新的图形界面开发包javax.swing包。Swing包在AWT包的基础上,完全采用Java语言开发,实现了图形界面的跨平台。Swing包提供了支持跨平台功能的更加丰富的组件库,也称为轻量级组件。而把AWT 的组件称为重量级组件。
JAVA从入门到实践
10.7 Applet
AWT包中的panel类有个特殊的子类java.applet.Applet类。Applet是用Java语言编写的小应用程序,嵌入到Web页面中在客户端浏览器执行。每个Applet都有其生命周期,分为初始化、运行、停止、消亡。对于Applet的相关知识,下面进行详细介绍。
JAVA从入门到实践
10.7.1 Applet简介
Apple是用Java语言编写的小应用程序的简称,可以直接嵌入到网页中运行,并能够产生特殊的效果。在Java Applet中,可以实现图形绘制、字体和颜色控制、动画和声音的插入以及人机交互、网络交流等功能。
Applet程序的执行方式不同于一般的Java程序。一般的Java程序执行是从它的main()方法被调用开始的,而一个Applet通常不包含main()方法。Applet程序通常是被嵌入到HTML页面中,由支持Java程序的Web浏览器执行。开发、执行Applet程序的主要步骤如下所示。
(1)编写Java Applet源程序。
(2)将Applet源程序编译生成为字节码文件。
(3)在HTML页面文件中使用