配套课件:Java语言程序设计

上传人:壹****1 文档编号:568592008 上传时间:2024-07-25 格式:PPT 页数:780 大小:16.70MB
返回 下载 相关 举报
配套课件:Java语言程序设计_第1页
第1页 / 共780页
配套课件:Java语言程序设计_第2页
第2页 / 共780页
配套课件:Java语言程序设计_第3页
第3页 / 共780页
配套课件:Java语言程序设计_第4页
第4页 / 共780页
配套课件:Java语言程序设计_第5页
第5页 / 共780页
点击查看更多>>
资源描述

《配套课件:Java语言程序设计》由会员分享,可在线阅读,更多相关《配套课件:Java语言程序设计(780页珍藏版)》请在金锄头文库上搜索。

1、第1章了解Java语言本章内容1.1Java的发展史1.2Java技术1.3Java语言的特点1.4Java的应用领域1.5Java开发环境1.6NetbeansIDE8.1环境介绍1.7一个简单的Java应用程序1.1Java的发展史1991年,美国Sun公司开始研究家用消费类电子设备。在Sun公司内部,JamesGosling领导的Green小组专注于软件方面研究,该小组在开始阶段选择已经非常成熟的C/C+语言进行开发和设计,C+程序需要消耗大量内存,而且还不能对不同设备的兼容。Green小组决定开发一种名为Oak的新语言。Sun公司于是对Oak语言进行重新命名为Java。随着互联网发展,

2、急需一种面向网络编程,能够在不同终端设备、不同的操作系统运行的语言。Java与浏览器结合,让Java得到进一步发展。Sun公司开发JDK。Java的发展史-JDK发布历程1995年3月,Sun公司正式向外界发布Java语言,Java语言正式诞生。 1996年1月,Sun公司公开发布JDK1.0。 1997年2月,Sun公司公开发布JDK1.1。1998年12月,Sun公司公开发布JDK1.2,这是Java语言的里程碑,Java也被首次划分为J2SE/J2EE/J2ME三种开发技术。从此以后,被国内开发者开始学习和使用Java语言。 2000年5月,Sun公司公开发布了JDK1.3。 Java的

3、发展史-JDK发布历程2002年2月,Sun公司公开发布了JDK1.4。 2004年10月,Sun公司公开发布了JDK1.5,同时Sun公司还将JDK1.5改名为J2SE5.0。 2006年6月,Sun公司公开发布了JDK1.6,也称JavaSE6.0,同时Java的各版本去掉2的称号,J2EE更名为JavaEE,J2SE更名为JavaSE,J2ME更名为JavaME。2006年12月,Sun公司SUN公司发布JRE6.0。2009年4月,Oracle公司(甲骨文公司)收购Sun公司,从而取得了Java的版权。2011年7月,Oracle公司发布java7.0的正式版。2014年3月,Orac

4、le公司发布java8.0的正式版,该版本增加了lambda、Default、Method等特性。2017年9月,Oracle公司发布了java9.0的正式版。2018年4月,Oracle公司发布了java10.0的正式版。Java的发展史2018年5月的TIOBE编程语言排行榜1.2Java技术当前Java技术主要包括:Java嵌入技术JavaSEJavaEEJava云。1.3Java语言的特点同C+语言相比,Java语言相对简单。Java语言是一种面向对象的程序设计语言。Java语言是面向计算机网络的高级编程语言,该语言可实现分布式编程。Java语言是健壮的。Java语言是安全的。Java

5、语言是可移植的。Java语言是支持即时编译器。Java运行效率非常高。Java语言支持多线程。Java语言支持动态加载。1.4Java的应用领域各种手机应用程序App行业和企业信息化电子政务及办公自动化嵌入式设备及消费类电子产品大数据技术高频交易领域软件工具1.6Java开发环境目前主要采用的集成开发环境有:Eclipse、MyEclipse以及NetBeans等。开发工具准备:从Oracle网址处下载最新的JDK安装包。从beans.org网站上下载最新的netbeans软件。设置环境变量在Windows7中,开发者按控制面板-系统和安全-系统-高级系统设置顺序进行单击操作Java运行环境J

6、RE(JavaRuntimeEnvironment)就是java程序运行环境NetbeansIDE8.1环境介绍NetbeansIDE8.1环境介绍(续)NetbeansIDE8.1环境介绍1.7一个简单的Java应用程序本章结束!第2章Java语言基础知识本章内容2.1Java的标识符2.2注释2.3Java的基本数据类型2.4常量2.5变量2.6运算符和表达式2.1Java的标识符Java符号主要由标识符、关键字(有时又称关键字)、运算符、分隔符等5种符号组成。Java标识符的命名规则是:以字母、下划线、美元符开头,其后若干个字母、汉字、下划线、美元符或数字,且长度没有限制。PI、$myf

7、ile、_systemTime、current_time是合法的表示符。而#name、3times、*a等是非法的标识符。定义标识符应该注意情况(1)Java标识符对大小写敏感。(2)Java的关键字不能作为标识符。(3)命名Java标识符时应该遵循一些约定。(a)给类和接口命名时,每个标识符的首字母都应大写(b)给变量和方法命名时,常采用骆驼式命名法。当变量名或方法名是由一个或多个单词连结在一起时,第一个单词以小写字母开始;第二个单词的首字母大写或每一个单词的首字母都采用大写字母,以此类推。(c)给常量命名时,基本数据类型的常量名中的字母都应该大写字母,字与字之间用下划线分隔。Java的关键

8、字关键字关键字使用场合使用场合private、public、protected访问控制abstract、 class、 extends、 final、implements、interface、native、static,synchronized、 transient、 volatile、new类、方法和变量修饰符break、continue、return、do、while、ifelse、 switch、 case、 default、 for、intanceof程序控制语句catch、finally、throw、throws、try错误处理import、package包相关boolean、byt

9、e、char、double、float、int、long、short、null、false、true基本数据类型this、super、void变量引用分隔符分号表示语句的结束标记、for循环中分隔不同表达式成分。逗号表示在方法声明或调用的参数列表中用于分隔多个参数,也可以在同一声明语句中同时声明多个属性或局部变量时起分隔作用。圆点表示访问对象成员时标明调用和隶属关系。空格用于分隔源代码的不同的部分。花括号表示用于限定语句块的范围,必须成对使用。返回目录2.2注释单行注释,在语句中以/开始至本行行尾。多行注释,以/*开始,以*/结束。/*到*/之间的若干行内容都是注释内容。文档注释,以/*开始,

10、以*/结束。注释若干行,并可以被Java文档工具写入Javadoc文档。可以使用author等标签;方法注释要紧靠方法的前面,可以在其注释中使用param、return、throws等标签。字段注释只有public的字段才需要字段注释,这些字段通常是static的。2.3Java的基本数据类型各种简单数据类型关关键字字 数据数据类型型存存储空空间大大小小默默 认值取取值范范围int整型40long长整型80short短整型20byte字节型10float单精度浮点型40fdouble 双精度浮点型80dboolean布尔型1falsefalse,truechar字符型20返回目录2.4常量常量

11、是指在程序运行时其值不会变化的量。在Java语言中,根据数据类型不同,常量可分为整型常量、实数常量、字符常量、布尔常量。整型常量整型常量包括int、long、short、byte四种类型的常量。在Java语言中,整型常量有四种表示形式,它们分别是:十进制、二进制、八进制、十六进制。(1)十进制整数,以非0数字开头的整数,其他数位可以是09。(2)二进制整数,是以0b开头的整数,数位只有0和1。(3)八进制整数,是以0开头的整数,数位可以是07。(4)十六进制整数,是以0x或0X开头的整数,数位可以是09、a、b、c、d、e、f、A、B、C、D、E、F。浮点常量字符常量字符常量是用英文单引号括起

12、来的单个字符或者用开头的转义符。Java最初采用16位Unicode编码(UTF-16)来表示字符。转义字符加编码形式有以下两种办法:(1)xxx:采用1到3位八进制数(xxx)来表示字符。(2)uxxxx:采用4位十六进制数(xxxx)来表示字符。字符常量-Java中的常用转义字符字符字符unicode值值说明说明tu0009制表符nu000a换行符ru000d回车符u0027单引号”u0022双引号u005c反斜杠bu0008退格符字符常量(续)例2-2Const.Java是关于转义字符使用的例子。1publicclassConst2publicstaticvoidmain(Stringa

13、rgs)34System.out.println(1:abc/de);5System.out.println(2:atbtc);6System.out.println(3:an);7/字符A的ASCII码是65,对应于八进制是101,8/字符a的ASCII码是97,对应于十六进制是619System.out.println(4:101u0061);10/rn先回车再换行;11System.out.println(5:arnb);12/nr先换行再回车;13System.out.println(6:anrb);1415字符串常量字符串常量是一对双引号括起来的字符序列。”goodmorning”、

14、”Javaprogram!”、”a”、”边长t边长t边长t面积n”。问题:“a”与a的区别?返回目录2.4变量变量是内存中的一段存储空间的名字,变量的值就是其对应存储空间内的值。变量的值随着程序的运行而动态变化。其格式如下:数据类型变量名称1=value1,变量名称2=value2,;例如,floata,b,c;/;/声明3个float类型的变量doublei=3.1,j=4.2;/声明两个变量i,j,并对它们进行初始化。变量-赋值运算赋值运算的格式如下:变量=表达式;inta,b;floatc,d,e;a=3;c=3.14f;d=c+100;e=0.618;vJava数据类型自动转换的顺序是

15、:vdoublefloatlongintcharshortbyte变量-强制数据类型转换强制数据类型转换方式为:变量=(强制数据类型)(表达式);说明:当表达式是一个简单变量或者是一个常量时,可以省略()。变量-强制数据类型转换例2-3关于强调数据类型的例子。1publicclassVaryTest2publicstaticvoidmain(Stringargs)3inta,b;4floatc;5charch;6a=(int)(7.1+4.2);7b=(int)1.618f;8c=(float)3.14;9ch=(char)97;10System.out.println(a=+a+,b=+b+

16、,c=+c);11System.out.println(ch=+ch);1213返回目录2.6运算符和表达式运算符是指明操作数的运算方式。组成表达式的运算符有很多种。单目运算符:只对一个操作数进行运算的运算符。例如,-、+、-。双目运算符:对两个操作数进行运算的运算符。例如,+、*、/。三目运算符:需要三个操作数才能进行运算的运算符。Java中只有条件运算符(?:)是三目运算符。表达式是由操作数和运算符按照规定的语法规则组成的式子。算术操作符算术运算符即算术运算符号。是完成基本的算术运算 (arithmetic operators) 符号。在Java语言中,算术运算符可分为单目算术运算符和双目

17、算术运算符。算术操作符-双目算术运算符运运算算符符使使 用用样式样式功能描述功能描述举例举例+a+ba与b相加3+4,3.1+2.4-a-ba减去b4-1,3.1-5.6*a*ba乘以b2*3,r*r*3.14(r是变量,r=2)/a/ba除以b8/3,8.0/3.0%a%ba除以b后的余数(b0)10%3,23%10,10.6%3.1算术操作符-单目算术运算符运算符运算符 使用样式使用样式功能描述功能描述例子例子+a+或+aa+,先使用a,然后a自增+a,先让a自增,然后使用a值b=i+;c=+i-a或-aa-,先使用a,然后a自减-a,先让a自减,然后使用a值b=i-;c=-i;-a得到a

18、的相反数b=-a;关系操作符关系运算符就是指两个操作数之间的关系。运运算算符符使使用用样样式式功能描述功能描述例子例子aba大于bx100aba小于bb*b-4*a*c0=a=ba小于等于bx=a=ba大于等于by=0b*b-4*a*c=0逻辑操作符运运 算算符符使使用用样样式式功能描述功能描述例子例子&a&ba和b同时为true时,a&b为truex3&x10|a|b在a和b中,只要一个为true时,a&b为truex10!a等于a的相反值!(x=0&x0&b0&c0)&(a+bc&a+cb&b+ca)a=10或者!(3a&a10)。位操作符运算符运算符使用样式使用样式功能描述功能描述a对a

19、的每个二进制位(包括符号位)取反,即把1变为0,把0变为1。&a&ba和b对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,否则为0。|a|ba和b对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1。aba和b对应的二进位相异或,当两对应的二进位相异时,结果为1。aan右移n位,最左边补符号位,就是除以2的n次方an无符号右移n,忽略符号位,空位都以0补齐位操作符-举例例2-10a和b是byte类型,a=6,b=-13,求a和b的值位操作符-举例例2-11a和b是byte类型,a=6,b=-13,求a&b、a|b、ab的值,位操作符-举例例2-12a和b是byte类型

20、,a=6,b=-13,求a2、b2的值。位操作符-举例例2-13a和b是byte类型,a=6,b=-13,求a2、b0)(x10)?x+3:x):2*x-1;其它运算符new运算符的作用是:创建对象或者为数组分配空间。instanceof运算符的作用是:判断对象是否是类的实例。例2-16关于 instanceof运算符的例子。1publicclassInstance2publicstaticvoidmain(Stringargs)3Integera=3;4if(ainstanceofInteger)/Integer是整型类型类是整型类型类5System.out.println(a+是整数是整数

21、);6else7System.out.println(a+不是整数不是整数);89运算符优先级优先优先级级运算运算符符符符号号名称名称结合性结合性(与与操作数操作数)操作数目操作数目数数说明说明1.点点从左到右从左到右双目双目()圆括号圆括号方括号方括号2+正号正号从右到左从右到左单目单目-负号负号单目单目+乘乘单目单目前缀增,后缀增前缀增,后缀增-自减自减前缀减,后缀减前缀减,后缀减按位非按位非/取补运算取补运算单目单目!条件取反条件取反单目单目3*乘乘从左到右从左到右双目双目/除除双目双目%取余取余双目双目4+加加从左到右从左到右双目双目-减减双目双目5带符号右带符号右移位运算移位运算符符

22、双目双目无符号右无符号右移移双目双目运算符优先级优先优先级级运算符符号运算符符号名称名称结合性结合性(与操与操作数作数)操作数目数操作数目数说明说明6小于小于从左到右从左到右双目双目关系运算符关系运算符“大于大于”说明说明大于大于双目双目=大于或等于大于或等于双目双目instanceof确定某对象是确定某对象是否属于指定的否属于指定的类类从左到右从左到右双目双目7=等于等于从左到右从左到右双目双目关系运算符关系运算符“=”说说明明!=不等于不等于双目双目8&按位与按位与从左到右从左到右双目双目9|按位或按位或从左到右从左到右双目双目10按位异或按位异或从左到右从左到右双目双目11&与与从左到右

23、从左到右双目双目12|或或从左到右从左到右双目双目13?:条件运算符条件运算符从右到左从右到左三目三目14=赋值运算符赋值运算符从右到左从右到左双目双目+=、-=、*=、/=、%=、&=、|=、=、=、=混混合合赋赋值值运运算算符符从右到左从右到左双目双目a=b相当于相当于a=ab,其,其中中可以是可以是+、-、*等。等。本章结束!第3章结构化程序设计本章内容3.1结构化程序设计的基本结构3.2简单语句3.3分支语句3.5循环语句3.1传统的程序流程图中的基本结构结构化程序设计的规则采用自顶向下、逐步求精及模块化的程序设计方法。为了使程序能够易读性,主要使用顺序、选择、循环三种基本程序控制结构

24、。(1)主张使用顺序、选择、循环三种基本结构来构造具有复杂层次的结构化程序,严格控制goto语句的使用。(2)“自顶而下,逐步求精”的设计思想。(3)“模块功能独立,单出、单入口”的模块结构。传统的程序流程图中的基本结构(a)选择分支;(b)输入或输出;(c)过程处理;(d)程序的开始或结束;(e)程序执行方向。基本程序控制结构1.顺序结构基本程序控制结构2.选择结构基本程序控制结构3.多分支结构基本程序控制结构4.循环结构(a)当型循环结构(b)直到型循环结构返回目录3.2简单语句Java的语句主要有:变量和函数声明性语句、表达式语句、函数调用语句、空语句、复合语句、控制语句(包括分支语句、

25、循环语句等)。而简单语句包括表达式语句、函数调用语句、空语句。1.表达式语句表达式语句分号是语句的重要组成部分,表达式语句是由表达式和分号构成,其格式形式分号是语句的重要组成部分,表达式语句是由表达式和分号构成,其格式形式为:表达式为:表达式;例如:例如:a+;+i;b=3+a;2.调用函数语句调用函数语句在编程过程中,经常要调用系统的库函数或者自定义的函数。其格式形式:在编程过程中,经常要调用系统的库函数或者自定义的函数。其格式形式:函数名函数名(参数列表参数列表);或者或者变量变量=函数名函数名(参数列表参数列表);如:如:System.out.println(“hello,howarey

26、ou!”);c=max(a,b);/调用自定义函数,求出变量调用自定义函数,求出变量a,b中的最大值,并将结果赋给中的最大值,并将结果赋给c。3.复合语句复合语句复合语句中可以包含若干条语句,这些语句可以是简单语句或者复合语句。复合语句中可以包含若干条语句,这些语句可以是简单语句或者复合语句。复合语句的形式:复合语句的形式:说明性语句说明性语句执行性语句执行性语句简单语句 在进行软件开发时,刚开始很多函数或模块都没有被编写出来。这时,可在调用这些函数或模块处,先添加一条空语句,以便将来调用这些函数或模块。空语句的形式:;/在此,可以调用函数数据的输入和输出1.标准的输入System.in.re

27、ad();2.Scanner类从Java的SDK1.5开始,Java新增加了java.util.Scanner类,这是一个用于扫描输入数据的实用类。可以使用Scanner类创建一个对象。例如:Scannerrd=newScanner(System.in);如果需要输入汉字时,定义形式:Scannerrd=newScanner(System.in,gbk);3.标准的输出 System.out最主要的方法有:print(),println()和write()等。数据的输入和输出例3-1输入数据例子。1publicclassInputs2publicstaticvoidmain(Stringarg

28、s)3floata;4intb;5Stringc;6Scannerrd=newScanner(System.in);7a=rd.nextFloat();8System.out.println(a);9System.out.println(rd.hasNextFloat();10b=rd.nextInt();11System.out.println(rd.hasNextInt();12c=rd.nextLine();13System.out.println(c);1415返回目录3.3分支语句-if在Java语言中,分支语句主要有:if语句和switch语句。if语句的一般形式:if(P)Ael

29、seB简单形式:if(P)A;分支语句例3-2输入一个数,判定它是否是奇数。1publicclassOddEven2publicstaticvoidmain(Stringargs)3Scannerrd=newScanner(System.in);4intn;5System.out.print(输入一个整数:);6n=rd.nextInt();7if(n%2=1)8System.out.println(n+是奇数。);9else10System.out.println(n+是偶数。);1112分支语句-if例3-4输入一元二次方程的系数,求解方程的根。1publicclassQuadraticE

30、quation2publicstaticvoidmain(Stringargs)3Scannerrd=newScanner(System.in);4doublea,b,c,d;5doublex1,x2;6System.out.println(输入一元二次方程的系数输入一元二次方程的系数a,b,c(其中其中a0):);7a=rd.nextDouble();8b=rd.nextDouble();9c=rd.nextDouble();10d=b*b-4*a*c;11if(d=0)1213x1=(-b+Math.sqrt(d)/(2*a);14x2=(-b-Math.sqrt(d)/(2*a);15S

31、ystem.out.println(输入一元二次方程的根:输入一元二次方程的根:);16System.out.print(x1=+x1);17System.out.println(,x2=+x2);1819else20System.out.println(该一元二次方程无实数根该一元二次方程无实数根.);2122分支语句-switchswitch语句的一般形式是:分支语句-switchbreak语句的格式:break标号;在在switch语句和循环语句中,如果遇见了语句和循环语句中,如果遇见了break语句,程序语句,程序会跳转到标号所管辖的地方之外。而如果省略了标号会跳转到标号所管辖的地方之

32、外。而如果省略了标号,则退则退出当前的出当前的switch或循环语句。或循环语句。分支语句-switch例3-5某商家,为了提高商品销量,对销售产品(假定统一零售单价为20元)实行打折活动;设用户购买该公司产品的数量为m;如果,用户可以得到1%的优惠。如果,用户可以得到3%的优惠。如果,用户可以得到4%的优惠。如果,用户可以得到5%的优惠。输入用户的购买数量m,求用户实际花销。1publicclassBuyProduct2publicstaticvoidmain(Stringargs)3Scannerrd=newScanner(System.in);4intm,s;5doublec,t;6Sy

33、stem.out.println(输入产品数量:输入产品数量:);7m=rd.nextInt();8s=m/500;9switch(s)1011case0:12c=0.01;13break;14case1:15c=0.03;16break;17case2:18case3:19c=0.04;20break;21default:22c=0.05;2324t=20*m*(1-c);25System.out.println(购买产品的花销是购买产品的花销是.+t);2627如果去掉break,将怎样?3.5循环语句while语句的一般形式是:while(P)A;while语句是先是判断条件P是否成立,

34、如果成立,就执行循环体A,这样反复执行循环体A若干次,一旦条件P不成立,就跳出循环。先执行循环体A,反复执行若干次,直到当条件P不满足时,就不执行循环体A,程序就跳出该循环。dowhile语句的一般形式:doAwhile(P);循环语句例例3-6输入一个大于输入一个大于1的正整数的正整数n,求求1+2+3+n。分析:输入n=5;初始条件循环条件循环体S=0,i=1i=n(5)【s=s+I,i=i+1】1=5Yess=s+i=0+1=1,i=i+1=1+1=22=5Yess=s+i=1+2=3,i=i+1=2+1=33=5Yess=s+i=3+3=6,i=i+1=3+1=44=5Yess=s+i

35、=6+4=10,i=i+1=4+1=55=5Yess=s+i=10+5=15,i=i+1=5+1=66=5No跳出循环输出结果s=151publicclassSum2publicstaticvoidmain(Stringargs)3Scannerrd=newScanner(System.in);4intn,i,s;5booleanflag=true;6System.out.println(输入一个正整数:);7n=rd.nextInt();8i=1;9s=0;10while(i=n)11s=s+i;12i+;1314System.out.println(和=+s);1516循环语句-forfo

36、r语句的一般形式是:for(表达式1;表达式2;表达式3)A;循环语句-forfor(i=a;i=b;i=i+c)A;for(i=a;i=b;i=i+1)A;循环语句-for例3-7输入n(下面n=8),输出的如图所示图形。循环语句-for例3-7代码1publicclassTriangleStar2publicstaticvoidmain(Stringargs)3intn,i,j,p=40;4Scannerrd=newScanner(System.in);5System.out.print(输入n:);6n=rd.nextInt();7System.out.println(输出的图形如下:)

37、;8for(i=1;i=n;i+)9for(j=1;j=p-i;j+)/输出p-i个空格10System.out.print();11for(j=1;j=2*i-1;j+)/输出2*i-1个*12System.out.print(*);13System.out.println();141516循环语句-for例3-8输入一个数,判断它是否是素数。1publicclassPrime2publicstaticvoidmain(Stringargs)3Scannerrd=newScanner(System.in);4intn,i,t;5System.out.println(输入一个正整数:);6n=

38、rd.nextInt();7t=(int)Math.sqrt(n);8for(i=2;it)16System.out.println(n+是素数。);17else18System.out.println(n+不是素数。);1920continue语句continue的作用是:结束本次循环,跳过循环体中尚未执行的语句。并再次判断循环条件,从而决定是否继续执行循环体。continue语句的格式有以下两种:(1)continue;(2)continue标号;continue语句例3-9输出100以内的素数。1publicclassPrimes2publicstaticvoidmain(Stringa

39、rgs)3Scannerrd=newScanner(System.in);4intn,i,t;5System.out.println(100以内的素数如下以内的素数如下:);6AllPrime:7for(n=2;n100;n+)8t=(int)Math.sqrt(n);9for(i=2;it)15System.out.print(n+);1617System.out.println();1819本章结束!第4章简单的类和对象本章内容4.1面向对象技术4.2属性和方法4.3类的定义和创建对象4.4构造方法4.5对象成员属性的初始化4.6访问权限修饰符4.7方法的参数传值方式4.1面向对象技术80

40、年代,人们提出了面向对象OO(Object-Oriented)方法。面向对象技术的基本思想:客观世界的万物都是对象。面向对象技术的基本特征包括:(1)抽象性(2)继承性(3)封装性(4)多态性。4.2属性和方法1.属性属性要描述一个对象主要从两个方面来进行,一看它有什么特性(即属性),二看它能做什么(即方法),这是外界认可它该有的功能。对象的属性,是对对象某方面的具体描述。2.方法在面向对象程序中,方法可以看成对象的功能或者类的功能。属性和方法方法定义的语法格式如下:修饰符方法返回值的类型方法名字(形参列表)由若干条语句组成的方法体方法名字方法名字:方法名字命名规则与类名、属性名命名规则基本一

41、致,但通常建议方法名以英文中的动词开头。方法返回值类型方法返回值类型:返回值类型可以是Java语言允许的任何数据类型,包括基本类型和复合类型;如果声明了方法返回值类型,则方法体内必须有一个有效的return语句,该语句返回一个表达式(它的类型与方法的返回值类型一致)。此外,如果一个方法没有返回值,则必须使用void来声明没有返回值。return语句的格式:return表达式;属性和方法形参列表形参列表:形参列表用于定义该方法可以接受的参数,形参列表由若干个”参数类型形参名”构造而成,多组参数之间以英文逗号(,)分隔开,形参类型和形参名之间以英文空格隔开。一旦在定义方法时指定了形参列表,则调用该

42、方法时必须传入与之相同类型的参数列表。有时候,方法没有参数,则在调用该方法时,就不带任何参数,但方法的括号不能省略掉。属性和方法例4-1 定义三角形类,其中有一求面积方法。1publicclassTriangle4_12publicstaticdoublegetTriangleArea(doublea,doubleb,doublec)3doublep,s;4p=(a+b+c)/2;5s=Math.sqrt(p*(p-a)*(p-b)*(p-c);6returns;78publicstaticvoidmain(Stringargs)9doublea=3,b=4,c=5;10doubles=get

43、TriangleArea(3,4,5);11System.out.println(边长边长a=+a+,b=+b+,c=+c+,面积面积=+s);1213属性和方法递归和递归方法有些时候,存在一些方法,经常会调用自身,称这种方法调用方式为递归,而该方法又称为递归方法。属性和方法例4-2输入整数n,求n!。1publicclassRecursion2publicstaticdoublefun(intn)3if(n=0|n=1)4return1;5else6returnn*fun(n-1);78publicstaticvoidmain(Stringargs)9doubles=fun(4);10Sys

44、tem.out.println(4!=+s);1112分析:n!=n*(n-1)!3!=3*2!2!=2*1!0!=1!=14.3类的定义和创建对象对象是系统用来描述客观事物的一个实体,是构成系统的一个基本单位。类是对具有相同方法、属性的对象的概括描述。张三张三李四李四王五王五赵六赵六抽象老虎、狮子、猫、狗、马、兔子抽象类的定义和创建对象在Java语言中,类的最简单定义形式如下:类的修饰符class类名extends父类名若干个属性定义若干个构造方法定义若干个其他非构造方法的方法定义每个类可以有父类,父类可以通过“extends父类名”来指定。最常见的成员:属性、构造方法、以及其他非构造方法的

45、方法。类的定义和创建对象定义属性的语法格式如下:修饰符属性类型 属性名=默认值属性的语法格式说明如下:修饰符:可以从public、protected、private三个中选择一个修饰符,然后还可以与static、final组合起来修饰属性。属性类型:属性类型可以是Java语言允许的任何数据类型,包括基本类型和复合类型。属性名:属性名必则是一个合法的标识符。其要求跟类名命名类似。默认值:在定义属性时,还可以定义一个可选的默认值。定义对象的格式如下: 类名对象名;创建对象格式如下:new类名(参数类别);例如,可以声明一个三角形类:Trianglet;类的定义和创建对象例4-3输入一个正整数n,判

46、断n是否为素数。素数就是只能被1和自身整除的正整数,1不是素数,2是素数。1publicclassPrime2publicstaticBooleanisPrime(intn)3inti;4booleanyes=true;5if(n=1)6returnfalse;7for(i=2;i0&b0)returntrue;25returnfalse;2628publicvoidadjustName()29if(isRectangle()30if(a=b)31name=正方形正方形;32elsename=长方形长方形;33else34name=非长方形非长方形;3536/求周长方法求周长方法37publi

47、cdoublegetPerimeter()return(a+b)*2;38/求面积方法求面积方法39publicdoublegetArea()returna*b;40Override41/图形对象的字符串表示方法图形对象的字符串表示方法42publicStringtoString()43Stringmsg=name+:边长边长a=+a+,边长边长b=+b;44if(isRectangle()45msg=msg+,周长周长+getPerimeter()+,面积面积=+getArea();46returnmsg;4748publicstaticvoidmain(Stringargs)49Recta

48、ngler=newRectangle5;50r0=newRectangle();51r1=newRectangle(3);52r2=newRectangle(-2);53r3=newRectangle(5,4);54r4=newRectangle(-1,2);55inti;56for(i=0;ir.length;i+)57System.out.println(ri);58Rectangler1=newRectangle();59r1.Rectangle(10,20,长方形长方形);60System.out.println(r1);6162构造方法例4-5下面定义了Person类。1public

49、classPerson2Stringid;/身份证号3Stringname;/姓名4intage;/年龄5Stringaddress;/地址6/定义了未带参数的构造方法7publicPerson()8id=111;9name=未命名;10age=0;11address=未定;1213Override14publicStringtoString()15returnPerson+id=+id+,name=+name+,age=+age+,address=+address+;1617/定义了带参数的构造方法定义了带参数的构造方法18publicPerson(Stringid1,Stringname1

50、,intage1,Stringaddress1)19id=id1;20name=name1;21age=age1;22address=address1;2324publicstaticvoidmain(Stringargs)25/调用未带参数的构造方法调用未带参数的构造方法26Personp1=newPerson();27System.out.println(p1=+p1);28/带参数的构造方法。带参数的构造方法。29Personp2=newPerson(101,张三张三,18,湖北省武汉湖北省武汉市市);30System.out.println(p1=+p2);3132关键字this当一个

51、对象创建后,Java虚拟机(JVM)于是给这个对象分配了一引用自己的指针,this就是这个指针的名字。需要用到需要用到this的几种情况的几种情况:(1)方法参数与方法中的局部变量和成员变量同名的时候,成员变量就会被屏蔽,方法参数与方法中的局部变量和成员变量同名的时候,成员变量就会被屏蔽,此时若要访问成员变量则需要用此时若要访问成员变量则需要用”this.成员变量名成员变量名”的方式来引用成员变量。当然,的方式来引用成员变量。当然,在没有同名的情况下,可以直接用成员变量的名字,而不用在没有同名的情况下,可以直接用成员变量的名字,而不用this,但用了也不会,但用了也不会出错。出错。public

52、Person(Stringid1,Stringname1,intage1,Stringaddress1)id=id1;name=name1;age=age1;address=address1;publicPerson(Stringid,Stringname,intage,Stringaddress)this.id=id;this.name=name;this.age=age;this.address=address;改写成关键字this(2)通过this调用另一个构造方法-this(参数列表),这个仅仅在类的构造方法中,在别的地方不能这样用。(3)在方法中,需要引用该方法所属类的当前对象时候,

53、就可以直接用this。关键字this例4-6定义三角形类Triangle1的例子。1publicclassTriangle12privatedoublea,b,c;3Stringname=三角形三角形;4publicTriangle1()5this(10);67/等边三角形的构造方法。等边三角形的构造方法。8publicTriangle1(doublex)9this(x,x,x);1011publicTriangle1(doublex,doubley)12this(x,x,y);1314/一般三角形的构造方法一般三角形的构造方法15publicTriangle1(doublea,doubleb

54、,doublec)16this.a=a;17this.b=b;18this.c=c;19adjustName();/调整三角形的名字调整三角形的名字2059publicStringtoString()60Stringmsg=name+t+a+t+b+t+c;61if(isTriangle()62msg=msg+t+this.getPerimeter()+t+this.getArea();63returnmsg;6465publicstaticvoidprintHeader()66System.out.println(图形名称tt边长at边长bt边长ct周长t面积);6768publicstat

55、icvoidmain(Stringargs)69Triangle1t1,t2,t3,t4,t5;70t1=newTriangle1();/系统调用默认的构造方法71Triangle1.printHeader();72System.out.println(t1);/相当于t1.toString()73t2=newTriangle1(6);t3=newTriangle1(3,4);t4=newTriangle1(3,4,5);74System.out.println(t2);75System.out.println(t3);76System.out.println(t4);7778返回目录4.5对

56、象成员属性的初始化在创建对象时,不仅要为对象分配存储空间,还需要初始化对象的属性值。如果在创建对象时没有初始化对象的属性值,系统则按照默认值初始化对象的属性值。例如,如果属性的数据类型是int或double,则其默认值分别为0和0.0。如果对象的属性是引用数据类型,则系统规定其默认值为null。publicclassTriangledoublea=1,b=1,c=1;Stringname;/类别publicclassTriangledoublea=1,b=1,c=1;Stringname;/类别a=10;b=10;c=10;在对对象进行初始化的时候,可以使用非静态初始化块对对象进行初始化。在定

57、义类的时候,可以在声明类的属性变量时,并进行初始化工作。访问权限修饰符1.访问权限修饰符修饰成员变量和方法在Java中,在成员变量和方法前面修饰的访问权限修饰符主要有public,private,protected,有时成员变量和方法前面没有访问修饰符。范围范围访问访问控制修饰符控制修饰符类内部类内部包内部包内部子类子类包外部包外部默认默认(即可无访问修饰符即可无访问修饰符)是是是是否否否否public是是是是是是是是private是是否否否否否否protected是是是是是是否否Java访问控制符修饰属性和方法访问控制符修饰属性和方法访问权限修饰符范围范围访问访问控制修饰符控制修饰符类内部类

58、内部包内部包内部子类子类包外部包外部默认默认(即可无访问修饰符即可无访问修饰符)是是否否public是是是是private是否否否protected是否否否首先,对于用首先,对于用public来修饰的类,可以直接访问它。但不能直接访问来修饰的类,可以直接访问它。但不能直接访问用用private和和protected来修饰的类来修饰的类(但内部类除外但内部类除外)。被。被private、protected修饰的类一定是内部类,而且内部类只能被定义所在的类内修饰的类一定是内部类,而且内部类只能被定义所在的类内部被访问,并且它们不能作为超类。其次,无任何修饰的类叫友好类,部被访问,并且它们不能作为超

59、类。其次,无任何修饰的类叫友好类,在另外一个类中使用友好类创建对象时,需要确保它们都在同一包中。在另外一个类中使用友好类创建对象时,需要确保它们都在同一包中。访问权限修饰符例4-8观察Java访问控制符的区别。1packagePackageA;2publicclassPA3/保护访问修饰的属性可以在本类或本包内被访问。4protectedintid;5/被私有访问修饰的属性可以在本类内访问。6privateStringname;7Stringsex;/默认访问方式8/PA类内部定义的内部私有类PA19privateclassPA110publicvoidprint()11System.out.

60、println(在PA类内部定义的私有类PA1,仅供PA访问);121314/PA类内部定义的保护类PA215protectedclassPA216publicvoidprint()17System.out.println(在PA类内部定义的保护类PA2,仅供PA访问);18194.6static修饰符在创建类的实例时,每个实例都会创建属于自己的属性变量。但是在变量的声明中使用了static修饰符,则表明该成员变量属于类本身,独立于类的任何对象。这种成员变量称为静态变量(静态属性或者是类成员变量)。静态属性和静态方法不需要创建实例就可以使用,它们被称为类成员。如果类中包含类成员,在定义类的时候

61、,系统为类成员分配内存空间。在创建类的对象时,系统单独为每个对象的非类成员变量和非类成员方法分配内存空间。类成员方法可以访问类成员变量,而类成员方法不能访问非类成员变量。static修饰符非类成员方法内访问类成员变量的方式是:类名.类成员变量。非类成员方法内访问类成员方法的方式是:类名.类成员方法(参数列表),其中参数列表是可选项。当非类成员方法与类成员同属相同类时,则非类成员方法内访问类成员时,可以省略类名。static修饰符例4-7static修饰符应用举例。1publicclassStaticField2staticintcount=0;/类成员变量,被static修饰3Stringna

62、me=abc;/非类成员变量4publicstaticvoidprint0()5System.out.println(我是print0类成员方法);67staticvoidprint1()/类成员方法8print0();/调用类成员方法9System.out.println(count:+count);/类成员方法可以访问类成员变量10/类成员方法可以不能访问非类成员变量11/System.out.println(name:+name);1213publicvoidprint2()/非类成员方法14System.out.println(count:+count);1516publicvoidp

63、rint3()17/由于print3方法是在StaticField类中,可以省略该类名18System.out.println(name:+StaticField.count);19/非类成员方法可以访问类成员变量20System.out.println(count:+count);21/非类成员方法可以能访问非类成员变量22System.out.println(name:+name);23/调用类成员方法print1().24print1();2526publicstaticvoidmain(Stringa)27StaticFields=newStaticField();28s.print3

64、();2930static修饰符对类成员变量使用静态初始化块进行初始化的方法如下:static类成员变量=表达式;Java变量初始化工作过程流程如右图static修饰符例4-8Java对变量初始化工作举例。1publicclassTriangle22/第一步第一步:初始化初始化3privatestaticintid=1;/图形的编号图形的编号4doublea=1,b=1,c=1;5Stringname=三角形三角形;/类别类别6/初始化对象的属性,注意初始化对象的属性,注意不能省略不能省略7/第二步,执行静态的,且只执行一次第二步,执行静态的,且只执行一次8static910System.ou

65、t.println(静态初始化静态初始化(只执行一次只执行一次):id+-+id);11id=100;12f1();1314/第三步,执行动态的初始化第三步,执行动态的初始化1516System.out.println(动态初始化动态初始化:id=+id);17System.out.println(a=+a+,b=+b+,c=+c);18id=id+1;19a=10;b=10;c=10;20f2();/调用类成员方法调用类成员方法2122publicTriangle2()23System.out.println(构造方法:+id);24System.out.println(a=+a+,b=+b

66、+,c=+c);25a=100;b=100;c=100;2627publicstaticvoidf1()28System.out.println(我是类成员方法f1()哦);2930publicstaticvoidf2()31System.out.println(我是类成员方法f2()哦);3233Override34publicStringtoString()35returnTriangle+a=+a+,b=+b+,c=+c+,name=+name+;3637publicstaticvoidmain(Stringargs)38Triangle2t1=newTriangle2();39Syst

67、em.out.println(t1);40Triangle2t2=newTriangle2();41System.out.println(t2);4243变量的作用域Java变量包括成员变量(实例变量,属性)、本地变量(局部变量)、类成员变量(静态属性)。其中本地变量(局部变量)包括:(1)方法或代码块中定义的变量;(2)方法参数变量;(3)异常处理参数变量。Java变量是在一定区域范围内有效,称Java变量起作用的区域为变量的作用域。其中成员变量作用域是整个类。类变量的作用域是从它定义之后。访问权限修饰符Java访问控制符修饰属性和方法Java访问控制符修饰的类范围范围访访问问控控制制修饰符

68、修饰符类内部类内部包内部包内部子类子类包外部包外部默认默认(即可无访问修饰符即可无访问修饰符)是是否否public是是是是private是否否否protected是是是否范围范围访问访问控制修饰符控制修饰符类内部类内部包内部包内部子类子类包外部包外部默认默认(即可无访问修饰符即可无访问修饰符)是是否否public是是是是private是否否否protected是否否否4.7方法的参数传值方式当变量作为方法参数时,是以传值方式将对象变量的引用传递给方法。在方法内部,该变量的引用值不能被改变。不过如果该变量是对象变量时,可以修改该对象变量所指向的对象内容。例4-9参数的传递方式讲解。方法的参数传值

69、方式(续)1publicclassPara2Stringvalue;/参数的值参数的值3/对于简单变量对于简单变量,是传值方式是传值方式4publicstaticvoidvalue(Stringa,Stringb,Stringc,Stringd)5a=a.concat(b);6c=b;7d=newString(a);8System.out.println(改变变量值之后:改变变量值之后:a=+a+,b=+b+,c=+c+,d=+d);910publicstaticvoidchange(Paraa,Parab,Parac,Parad)11a.value=a.value.concat(b.valu

70、e);12c.value=b.value;13d.value=newString(a.value);14System.out.println(改变变量值之后:改变变量值之后:a=+a+,b=+b+,c=+c+,d=+d);1516Override17publicStringtoString()18returnvalue;1920publicstaticvoidmain(Stringargs)21Stringa,b,c,d;22a=aaa;b=bbb;c=ccc;d=ddd;23System.out.println(调用调用value之前:之前:a=+a+,b=+b+,c=+c+,d=+d);2

71、4value(a,b,c,d);25System.out.println(调用调用value之后:之后:a=+a+,b=+b+,c=+c+,d=+d);26Paraa1,b1,c1,d1;27a1=newPara();b1=newPara();c1=newPara();d1=newPara();28a1.value=aaaa;b1.value=bbbb;c1.value=cccc;d1.value=dddd;29System.out.println(调用调用change之前:之前:a1=+a1+,b1=+b1+,c1=+c1+,d1=+d1);30change(a1,b1,c1,d1);31S

72、ystem.out.println(调用调用change之后:之后:a1=+a1+,b1=+b1+,c1=+c1+,d1=+d1);3233本章结束!第5章数组本章内容5.1一维数组5.2多维数组5.3数组综合举例5.4Arrays类5.1一维数组一维数组定义的格式如下:数据类型 数组名;或者是:数据类型数组名;例如,定义如下数组:intscore;Stringcourse;doublearea;floatmathScore,englishScore;Trianglet;Personp;为数组分配存储空间格式如下:new数据类型数组大小;一维数组引用数组元素格式是:数组名整型表达式。注意:整型

73、表达式是数组元素的下标,其值是从0开始,并且必须小于数组大小。可以获取数组元素的个数(即数组长度):数组名.length。例5-1数组存储空间例子,注意数组元素的默认值。1publicclassTestArray12publicstaticvoidmain(Stringb)3inta=newint10;4Objectc=newObject10;5Stringd=newString10;6floate=newfloat10;7doublef=newdouble10;8charg=newchar10;9booleanh=newboolean10;10for(inti=0;i10;i+)11Syst

74、em.out.println(ai+ci+di+ei+fi+gi+hi);121314一维数组对于数组和集合类型,可以利用foreach循环语句,可以访问其中所有的元素。foreach循环语句格式如下:for(元素类型 变量:数组或集合名)循环体例5-2for语句举例。1publicclassTestArray32publicstaticvoidmain(Stringargs)3inta=newint10;/初始化时,各数组元素值为初始化时,各数组元素值为04inti;5for(i=0;ia.length;i+)6ai=100+i;7System.out.println(1处数组元素如下:处数

75、组元素如下:);8for(intj:a)9System.out.print(j+);10System.out.println();/换行换行11for(intj:a)12j=j+1000;/注意,此处无法改变数组元素的值注意,此处无法改变数组元素的值13System.out.println(2处数组元素如下:处数组元素如下:);14for(intj:a)15System.out.print(j+);16System.out.println();1718思考:思考:foreach语句能语句能否否完全完全取代取代for循环循环语语句句?一维数组定义例5-3for语句举例。1publicclassT

76、estArray32publicstaticvoidmain(Stringargs)3inta=newint10;/初始化时,各数组元素值为初始化时,各数组元素值为04inti;5for(i=0;i18a=newintn;/9inti,j;10for(i=0;in;i+)11ai=newinti+1;/声明数组元素声明数组元素ai是一维数组是一维数组,其元素个数为其元素个数为i+112ai0=aii=1;1314for(i=2;ia.length;i+)15for(j=1;ji;j+)16aij=ai-1j-1+ai-1j;17System.out.println(输出的杨辉三角情况如下:输出

77、的杨辉三角情况如下:);18for(i=0;ia.length;i+)19for(j=0;jai.length;j+)20System.out.print(aij+);21System.out.println();/换行换行222324二维数组二维数组的初始化(1)分行给二维数组初值,每对花括号内的数组对应一行元素。例如,intb=1,2,3,4,5,6,7,8,9,10,11,12;(2)各行的数组元素个数不一样多。例如,intc=1,2,3,4,5,6,7;(3)在定义时,动态分配存储空间,并为各个数组元素赋值。例如 inth=newint1,2,3,4,5,6,7,8;或者inth;h=

78、newint1,2,3,4,5,6,7,8;返回目录5.3数组综合举例例5-7输入若干个数,将最小数值跟第一个元素交换。1publicclassMinSwap2publicstaticvoidmain(Stringargs)3inta,i,j,n,t;4System.out.println(输入数组的元素个数:输入数组的元素个数:);5Scannersc=newScanner(System.in);6n=sc.nextInt();7a=newintn;8System.out.println(输入输入+n+个数组元素个数组元素:);9for(i=0;ia.length;i+)10ai=sc.ne

79、xtInt();11j=0;12/记录最小值的数组元素下标记录最小值的数组元素下标13for(i=0;iai)15j=i;16if(j!=0)/如果最小值的数组元素下标不等于如果最小值的数组元素下标不等于0时,则交换其值时,则交换其值17t=aj;aj=a0;a0=t;1819for(i=0;iai,则交换它们,一直比较到an。同样办法,对a1,a2,.an-1处理,即完成排序。例如,以7个数9734625为讲解冒泡排序,排序结果为升序。第第1趟排序情况:趟排序情况:数组下标数组下标01234569734625第第1次比较次比较a0与与a1,交换交换7934625第第2次比较次比较a1与与a2

80、,交换交换7394625第第3次比较次比较a2与与a3,交换交换7394625第第4次比较次比较a3与与a4,交换交换7349625第第5次比较次比较a4与与a5,交换交换7346925第第6次比较次比较a5与与a6,交换交换73462957346259数组综合举例第二趟排序情况如下:数组下标0123456734625【9】第1次比较a0与a1,交换734625【9】第2次比较a1与a2,交换374625【9】第3次比较a2与a3,交换347625【9】第4次比较a3与a4,交换346725【9】第5次比较a4与a5,交换346275【9】34625【79】依次类推:依次类推:第三趟排序之后,

81、结果如下:3425【679】第四趟排序之后,结果如下:324【5679】第五趟排序之后,结果如下:23【45679】第六趟排序之后,结果如下:2【345679】数组综合举例1publicclassBubbleSort2publicstaticvoidmain(Stringargs)3inta,n;4Scannersc=newScanner(System.in);5System.out.println(输入要排序数的个数输入要排序数的个数n(n1):);6n=sc.nextInt();/要求要求7a=newintn;8inti,j,t;9for(i=0;in;i+)1011System.out.

82、println(输入数组元素输入数组元素a+i+:);12ai=sc.nextInt();1314for(i=0;ia.length-1;i+)1516for(j=0;jaj+1)1819t=aj;aj=aj+1;aj+1=t;202122System.out.println(冒泡排序结果:冒泡排序结果:);23for(i=0;i1):);6n=sc.nextInt();/要求要求7a=newintn;8inti,j,t,k;9for(i=0;ia.length;i+)10System.out.print(输入数组元素输入数组元素a+i+:);11ai=sc.nextInt();/输入数组元素

83、输入数组元素1213for(i=0;ia.length;i+)14k=i;15for(j=i+1;jaj)17k=j;18if(k!=i)t=ak;ak=ai;ai=t;1920System.out.println(选择排序结果如下:选择排序结果如下:);21for(i=0;ia.length;i+)22System.out.print(ai+t);23System.out.println();2425数组综合举例例5-10顺序查找。1publicclassSequenceQuery2/输出数组输出数组3publicstaticvoidprint(intr)4System.out.printl

84、n(数据如下数据如下:);5for(inta:r)6System.out.print(a+);7System.out.println();/换行换行89/顺序查找:在数组顺序查找:在数组r中,查找值中,查找值value,如果找到,返回数组元素下标,如果找到,返回数组元素下标,否则返回否则返回-1。10publicstaticintsquenceQuery(intr,intvalue)11inti;12for(i=0;i=0)26System.out.println(找到找到+value+,它等于数组元素它等于数组元素r+result+);27else28System.out.println(在

85、数组在数组r中,不存在中,不存在+value+数数组元素!组元素!);2930数组综合举例例5-11二分法查找。1publicclassBinaryQuery2/二分查找二分查找3publicstaticintbinaryQuery(intr,intvalue)4intn=r.length-1;5intlow=0,high=n,mid=-1;6while(low=high)7mid=(low+high)/2;8if(rmid=value)9break;10else11if(rmidvalue)12low=mid+1;13else14high=mid-1;1516if(lowhigh)17ret

86、urnmid;18else19return-1;20返回目录5.4Arrays类主要方法如下:staticintbinarySearch(Ea,Ekey)使用二进制搜索算法来搜索指定的E型数组,以获得指定的值。staticvoidfill(Ea,Eval)将指定的E值分配给指定E型数组的每个元素。staticvoidfill(Ea,intfromIndex,inttoIndex,Eval)将指定的E值分配给指定E型数组指定范围中的每个元素。staticvoidsort(Ea)对指定的E型数组按数字升序进行排序。staticvoidsort(Ea,intfromIndex,inttoIndex)

87、对指定E型数组的指定范围按数字升序进行排序。说明:E可以是int、float、double、boolean、short、long、char、boolean等。staticintbinarySearch(Ta,Tkey,Comparatorc)使用二进制搜索算法来搜索指定数组,以获得指定对象。staticvoidsort(Ta,Comparatorc)根据指定比较器产生的顺序对指定对象数组进行排序。staticvoidsort(Ta,intfromIndex,inttoIndex,Comparatorc)根据指定比较器产生的顺序对指定对象数组的指定范围进行排序。Arrays类例5-12利用Arr

88、ays类对数组初始化,并排序。1publicclassArraysTest2/输出数组输出数组3publicstaticvoidprint(intr)4System.out.println(数据如下数据如下:);5for(inta:r)6System.out.print(a+);7System.out.println();89publicstaticvoidmain(Stringargs)10intr;11r=newint10;12Randomrandom=newRandom();/定义随机类对象定义随机类对象13Arrays.fill(r,0);/数组初始化数组初始化14inti;15for

89、(i=0;ir.length;i+)16ri=random.nextInt(100);/数组元素值在范围数组元素值在范围(0,100)17Arrays.sort(r);/数组排序数组排序18print(r);/输出数组输出数组1920返回目录本章结束!第6章复杂的类和对象本章内容6.1子类的定义6.2派生类的构造方法6.3方法继承、覆盖、重载6.3.1方法继承6.3.2方法覆盖6.3.3方法重载6.3.4多态6.3.5异类集合6.3.6final关键字6.1子类的定义单重继承是指子类(又称为派生类)的父类(也可以称为超类)只有一个。这种继承关系单一,是简单的树形结构,因而很容易被掌握和理解。如

90、下图所示,子类由父类继承而来。多重继承是指一个类有至少一个以上的父类。子类的定义在Java语言中,子类的定义格式如下:publicclass子类Aextends父类B在上面定义中,子类A是由父类B继承而来的。如果上面定义中省略了extends父类B,在Java语言中,认为子类A是由类Object继承而来的。子类的定义例6-1子类定义举例。publicclassPersonprivateStringid;/身份证号码privateStringname;/姓名privateStringsex;/性别privateStringbirthday;/出生日期publicclassCollegeStude

91、ntextendsPersonprivateStringschoolName;/学校名字privateStringstudentId;/学号privateStringmajor;/专业名称子类的定义例6-2对于三角形、圆形、长方形等,一般都有编号和名称,另外它们还有各自的属性。如三角形有3条边长,圆有半径,而长方形有4条边。publicclassFigureStringid;/图形编号Stringname;/图形编号staticintcount;/统计图形的个数。publicclassTriangleextendsFigurefloata,b,c;/三角形的三条边长;publicclassCi

92、rcleextendsFigurefloatr;/圆的半径;publicclassRectangleextendsFigurefloata,b;/长方形的边长6.2派生类的构造方法在定义派生类的构造方法时,应该注意以下情况:(1)在创建一个派生类(子类)对象时,派生类的构造方法首先调用超类(父类)的构造方法,然后执行派生类构造方法中的语句,对派生类新增的成员进行初始化工作;(2)在派生类构造方法中,可以使用super方法来调用超类的构造方法,调用super方法的语句要作为子类构造方法的第一条语句。调用super方法的格式:super(参数列表);需要注意的是:父类中必须定义带有相应参数列表形式

93、的构造方法。(3)如果派生类的构造方法中没有通过super方法来调用超类的构造方法,同时超类中亦不存在带形参的构造方法,则Java首先自动地调用超类默认的构造方法,负责超类数据成员的初始化工作,否则编译系统认为存在语法错误;(4)如果超类定义了带有形参表的构造方法,派生类就应该定义带形参的构造方法,同时在超类构造方法的第一条语句给出一个带形参的super调用,从而能够将参数传递给超类构造方法,保证超类能够进行初始化自己的数据成员。派生类的构造方法例6-3派生类举例,下面定义超类Parent和派生类Child。1publicclassParent2Stringname;3publicParent

94、()4System.out.println(调用默认父类的构造方法进行初始化调用默认父类的构造方法进行初始化);5name=newString(未定未定);6System.out.println(父类中的父类中的name:+name);78publicParent(Stringname)9System.out.println(调用带参数的父类构造方法进行初始化调用带参数的父类构造方法进行初始化);10this.name=newString(name);11System.out.println(父类中的父类中的name:+this.name);1213派生类的构造方法1publicclassCh

95、ildextendsParent2StringnickName;3publicChild()4System.out.println(调用孩子类的默认构造方法调用孩子类的默认构造方法);5nickName=newString(未定义未定义);6System.out.println(孩子类的孩子类的nickName:+nickName);78publicChild(StringnickName,Stringname)9super(name);/调用父类的构造方法调用父类的构造方法10System.out.println(调用孩子类带参数的构造方法调用孩子类带参数的构造方法);11this.nick

96、Name=newString(nickName);12System.out.println(孩子类的孩子类的nickName:+nickName);1314publicstaticvoidmain(Stringargs)15Childch=newChild();16Childch1=newChild(二狗二狗,狗爸狗爸);1718返回目录6.3方法继承一般情况下,子类可以继承父类定义的一些方法(这些方法无访问权限修饰符修饰,或者被protected、public访问权限修饰符修饰)。如果子类中存在名字与之相同方法时,在子类中调用这些方法之前需加上“super.”;另外一方面,在子类中不存在名字

97、与之相同的方法,子类中可以直接调用父类的方法(即可以省略super.修饰符)。方法继承例6-5定义父类FatherClass和其子类SonClass。1publicclassFatherClass2publicvoidfun1()3System.out.println(父类父类:具有功能具有功能fun1();45publicvoidfun2()6System.out.println(父类父类:具有功能具有功能fun2();78publicvoidfun3()9System.out.println(父类父类:具有功能具有功能fun3();10111publicclassSonClassexten

98、dsFatherClass2publicvoidfun3()3super.fun3();/调用父类的调用父类的fun3()方法,此处的方法,此处的super.不能省略。不能省略。4System.out.println(子类子类:fun3();56publicvoidfun4()7super.fun1();/调用父类的调用父类的fun2()方法,此处的方法,此处的super.能省略能省略8fun2();/调用父类的调用父类的fun2()方法,此处可以加上方法,此处可以加上super.9System.out.println(子类子类:fun4();1011publicvoidfun5()12Sys

99、tem.out.println(子类子类:fun5();1314publicstaticvoidmain(Stringargs)15SonClassson=newSonClass();16son.fun1();/子类继承父类的方法子类继承父类的方法17son.fun2();/子类继承父类的方法子类继承父类的方法18son.fun3();/子类调用自己的方法子类调用自己的方法19son.fun4();/子类调用自己的方法子类调用自己的方法20son.fun5();/子类调用自己的方法子类调用自己的方法21226.3.2方法覆盖子类要覆盖父类方法时,应该满足下面条件:(1)子类的方法名称、返回类型

100、及参数表必须与父类的一致。(2)子类方法不能缩小父类方法的访问权限。(3)子类方法不能抛出比父类方法更多的异常。(4)方法覆盖只存在于子类和父类之间,同一个类中只能重载。也就是说同一类中,不能有两个名字、参数表等完全一致的方法。(5)父类的静态方法不能被子类覆盖成为非静态方法。(6)子类可以定义于父类的静态方法同名的静态方法,以便在子类中隐藏父类的静态方法(满足覆盖约束)。(7)Java虚拟机把静态方法和所属的类绑定,把实例方法和所属的实例绑定。(8)父类的非静态方法不能被子类覆盖为静态方法。(9)父类的私有方法不能被子类覆盖。(10)父类的抽象方法可以被子类通过两种途径覆盖(即实现和覆盖)。

101、(11)父类的非抽象方法可以被覆盖为抽象方法。方法覆盖例6-6有ParentClass类和SubClass类。1publicclassParentClass2publicvoidfunA()3System.out.println(父类父类:funA方法运行了。方法运行了。);45publicvoidfunB()6System.out.println(父类父类:funB方法运行了。方法运行了。);7funA();/调用调用funA()方法方法8System.out.println(父类父类:funB方法结束了。方法结束了。);910publicvoidfunC()11System.out.pri

102、ntln(父类父类:funC方法运行了。方法运行了。);12System.out.println(父类父类:funC方法结束了。方法结束了。);13141publicclassSubClassextendsParentClass2publicvoidfunA()3System.out.println(子类:子类:funA方法运行了方法运行了);4System.out.println(子类:子类:funA方法结束了方法结束了);56publicvoidfunB()7System.out.println(子类:子类:funB方法运行了方法运行了);8super.funB();/调用父类的调用父类的

103、funB()方法方法9System.out.println(子类:子类:funB方法结束了方法结束了);1011publicvoidfunC()12System.out.println(子类:子类:funC方法运行了方法运行了);13funA();/调用子类的调用子类的funA()方法,没有方法,没有super修饰符修饰符14System.out.println(子类:子类:funC方法结束了方法结束了);1516publicstaticvoidmain(Strings)17SubClasssc=newSubClass();18sc.funA();19sc.funB();20sc.funC()

104、;21226.3.3方法重载方法重载的要求:(1)方法名相同;(2)方法的参数类型,个数顺序至少有一项不同;(3)方法的返回类型可以不同,也可以相同;(4)方法的修饰符可以不相同;1publicclassFather2publicvoidprint()3System.out.println(Father类的打印方法类的打印方法:+无参数无参数!);45publicvoidprint(intx,Stringy)6System.out.println(Father类的打印方法类的打印方法:+x+,+y);78publicvoidprint(Stringy,intx)9System.out.prin

105、tln(Father类的打印方法类的打印方法:+x+,+y);1011例例6-7在类在类Father和和Son类中,定义了几个方法,它们属于方法类中,定义了几个方法,它们属于方法重载。重载。方法重载1publicclassSonextendsFather2publicvoidprint()3super.print();/调用父类的调用父类的print()方法方法4System.out.println(Son类:类:+无无);56publicvoidprint(intx,Stringy)7super.print(x,y);/调用父类的调用父类的print(intx,Stringy)方法方法8Sy

106、stem.out.println(Son类:类:+x+,+y);910publicvoidprint(Stringy,intx)11super.print(y,x);/调用父类的调用父类的print(Stringy,intx)方法方法12System.out.println(Son类的打印方法类的打印方法:+x+,+y);1314publicstaticvoidmain(Stringargs)15Sonson=newSon();16son.print();17son.print(a,10);18son.print(20,b);1920返回目录6.3.4多态面向对象的设计中有一条原则:父类出现的

107、地方,子类一定可以出现,反之则不一定;多态即是这一原则的具体表现形式,设有父类为ParentClass,其内包括一方法fun(),SubClass1、SubClass2、SubClassn都是父类ParentClass类的子类,每个子类都实现了各自的方法fun(),当调用各子类对象的fun()方法时,结果各子类对象将表现出不同的行为,这种现象即为多态。需注意的是:多态还屏蔽了父类的fun()方法。如果需要调用父类的fun()方法,则需要利用super关键字来调用父类的fun()方法。多态例6-8定义一Animal类,它有shout()、favoriteFood()和fun()方法,其子类Pup

108、py类和Pussy类亦包含有cry()、favoriteFood()方法,但各类调用cry()方法后,反应出其叫声不同。而调用favoriteFood()方法反映其所爱好食物不同。1publicclassAnimal2publicvoidcry()3System.out.println(Animal的叫声:的叫声:);45publicvoidfavoriteFood()6System.out.println(Animal爱吃的食物:爱吃的食物:);78publicfinalvoidfunc()9System.out.println(Animal:调用调用func()方法方法);1011多态1p

109、ublicclassPuppyextendsAnimal2publicvoidcry()3System.out.println(puppy:汪汪汪汪.);45publicvoidfavoriteFood()6System.out.println(puppy爱吃的食物有:肉肉,骨头、狗粮等爱吃的食物有:肉肉,骨头、狗粮等.);781publicclassPussyextendsAnimal2publicvoidcry()3System.out.println(Pussy:喵喵喵喵.);45Override6publicvoidfavoriteFood()7System.out.println(P

110、ussy爱吃的食物爱吃的食物:老鼠、鱼等老鼠、鱼等.);89多态例6-9定义一Human类,它有TermBegin()方法;Human类的子类Student类、Teacher类、Merchant类中也都有TermBegin()方法。Human类、Student类、Teacher类、Merchant类的对象调用TermBegin()方法,结果都不同。各类人(学生、老师、商人等)处理开学信息反应不同。1publicclassHuman2publicvoidtermBegin()/开学方法3System.out.println(人:我要做事。);451publicclassStudentextend

111、sHuman2publicvoidtermBegin()3System.out.println(学生:返校、选课、检查课表,准备上课。);45多态1publicclassTeacherextendsHuman2publicvoidtermBegin()3System.out.println(教师:准备教材、备课、查课表,准备上课。);451publicclassMerchantextendsHuman2publicvoidtermBegin()3System.out.println(商人:调查学生需要的各种商品、进货、摆好货物,供学生选购。);45返回目录6.3.5异类集合例6-10结合例6-

112、4中定义的各类,本例又定义ParameterOfFunction类,其中包含了getFigureName(Figuref)方法。该方法可以根据参数f是什么对象,返回图形的名称。异类集合1publicclassParameterOfFunction2publicStringgetFigureName(Figuref)3returnf.getName();45publicstaticvoidmain(Strings)6Trianglef1=newTriangle(3,4,5);7Trianglef2=newTriangle(3,3,3);8Rectanglef3=newRectangle(3,4)

113、;9Circlef4=newCircle(3);10ParameterOfFunctionp=newParameterOfFunction();11System.out.println(图形形状是:图形形状是:+p.getFigureName(f1);12System.out.println(图形形状是:图形形状是:+p.getFigureName(f2);13System.out.println(图形形状是:图形形状是:+p.getFigureName(f3);14System.out.println(图形形状是:图形形状是:+p.getFigureName(f4);1516异类集合inta

114、nceof运算符的使用方法是:类变量instanceof类名。在使用instanceof运算符判断了类对象是属于类的实例之后,可以强制转换该对象,强制转换对象的格式是:(类名)类对象。异类集合1publicclassPerson2privatelongid;/身份证编号身份证编号3privateStringname;/姓名姓名4privateDatebirthday;/出生日期出生日期5privateintage;/年龄年龄6publicPerson(Personp)7this(p.getId(),p.getName(),p.getBirthday();89publicPerson(longi

115、d,Stringname,Datebirthday)10this.id=id;11this.name=name;12this.birthday=birthday;13Datenow=newDate();14age=now.getYear()-birthday.getYear();/下面是计算大致年龄下面是计算大致年龄15intmm=now.getMonth()-birthday.getMonth();16if(mm0)17age=age-1;1836异类集合1publicclassCollegeStudentextendsPerson2privateStringschoolName;/学校名字

116、学校名字3privateStringmajor;/专业名称专业名称4privatefloatscore;/入学分数入学分数5publicCollegeStudent()6super(0,null,newDate();78publicCollegeStudent(Stringsn,Stringmajor,floatscore,Personp)9super(p);10this.schoolName=sn;11this.major=major;12this.score=score;1314publicvoidprintStudent()15super.printPerson();16System.o

117、ut.println(所读学校:所读学校:+schoolName);17System.out.println(所读专业:所读专业:+major);18System.out.println(入学成绩入学成绩:+score);1920publicvoidprint(Personp)21if(pinstanceofCollegeStudent)22(CollegeStudent)p).printStudent();23else24if(pinstanceofPerson)25p.printPerson();262734publicvoidprint(Personp)if(pinstanceofPer

118、son)p.printPerson();elseif(pinstanceofCollegeStudent)(Student)p).printStudent();返回目录6.3.6final关键字final关键字对于基本类型前用final修饰,表示被修饰的变量为常数(即一旦确定值之后,就不能被修改)。而且该变量必须在定义时或构造方法中进行初始化,如果在其它地方对它赋值时,将会报错。一个既是static又是final的变量表示它被保存在一段不能改变的内存空间,而且在定义时就必须对它进行初始化。final用于修饰对象时,final使该对象引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指

119、向另一个对象。而对于对象引用,不能改变的是它的引用,而对象本身是可以修改的。一旦final引用被初始化指向一个对象,该引用将不能再指向其它对象。例6-12用final修饰方法的例子,定义FatherOfFinal类和SonOfFinal类,其中前者是后者的父类。final关键字1publicclassFinalTest2finalintTRIANGLE;3finalintCIRCLE;4finalintRECTANGLE;5/PI必须在定义时,就被初始化必须在定义时,就被初始化6staticfinalfloatPI=3.14159f;7publicFinalTest()8this.TRIANG

120、LE=0;9this.CIRCLE=1;10this.RECTANGLE=2;1112publicFinalTest(intTRIANGLE,intCIRCLE,intRECTANGLE)13this.TRIANGLE=TRIANGLE;14this.CIRCLE=CIRCLE;15this.RECTANGLE=RECTANGLE;162930final关键字1publicclassSonOfFinalextendsFatherOfFinal2publicvoidfunA1()/该方法名不能改成该方法名不能改成funA()3System.out.println(SonOfFinal运行运行fu

121、ncA1()方法开始方法开始);4System.out.println(SonOfFinal运行运行funcA1()方法结束方法结束);56publicvoidfunC()7System.out.println(SonOfFinal运行运行funC()方法开始方法开始);8System.out.println(SonOfFinal运行运行funC()方法结束方法结束);910publicstaticvoidmain(Stringargs)11SonOfFinalson=newSonOfFinal();12son.funA1();13son.funB();/调用父类的调用父类的funB()方法方

122、法14son.funC();1516final关键字1publicclassSonOfFinalextendsFatherOfFinal2publicvoidfunA1()/该方法名不能改成该方法名不能改成funA()3System.out.println(SonOfFinal运行运行funcA1()方法开始方法开始);4System.out.println(SonOfFinal运行运行funcA1()方法结束方法结束);56publicvoidfunC()7System.out.println(SonOfFinal运行运行funC()方法开始方法开始);8System.out.println

123、(SonOfFinal运行运行funC()方法结束方法结束);910publicstaticvoidmain(Stringargs)11SonOfFinalson=newSonOfFinal();12son.funA1();13son.funB();/调用父类的调用父类的funB()方法方法14son.funC();1516本章结束!第7章常用类的使用本章内容7.1String类7.2StringBuffer类7.3正则表达式7.4基本数据类型的包装类7.5Object类7.6Math类7.1String类String对象的初始化由于String对象特别常用,所以在对String对象进行初始化

124、时,Java语言提供了一种简单的特殊语法,其格式如下:字符串变量名=字符串常量;例如,Stringstr=thisisJavaprogram”;String类的常用构造方法如下:String(charvalue):分配一个新的String,它表示当前字符数组参数中包含的字符序列。String(charvalue,intoffset,intcount):分配一个新的String,它包含来自该字符数组参数的一个子数组的字符。String(Stringoriginal):初始化一个新创建的String对象,表示一个与该参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的一个副本。String

125、(bytebytes,StringcharsetName)构造一个新的String,方法是使用指定的字符集解码指定的字节数组。String类例如:chars=j,a,v,a;Stringmsg=newString(s);Stringmsg1=newString(s,0,2);Stringmsg2=newString(“Java”);Stringmsg3=newString(msg1.getBytes(),”utf-8”); String类的主要方法String类charcharAt(intindex):返回指定索引处的char值。intcompareTo(StringanotherString

126、):按字典顺序比较两个字符串。intcompareToIgnoreCase(Stringstr):不考虑大小写,按字典顺序比较两个字符串。Stringconcat(Stringstr):将指定字符串联到此字符串的结尾。booleanendsWith(Stringsuffix):测试此字符串是否以指定的后缀结束。booleanequals(ObjectanObject):比较此字符串与指定的对象。booleanequalsIgnoreCase(StringanotherString):将此String与另一个String进行比较,不考虑大小写。intindexOf(intch):返回指定字符在此

127、字符串中第一次出现处的索引。intindexOf(Stringstr):返回第一次出现的指定子字符串在此字符串中的索引。intlength():返回此字符串的长度。Stringreplace(charoldChar,charnewChar):返回一个新的字符串,它是通过用newChar替换此字符串中出现的所有oldChar而生成的。Stringsplit(Stringregex):根据给定的正则表达式的匹配来拆分此字符串。当使用用字符ch来分隔字符串时,如果ch是转义字符时,则regex的值为ch”,例如设ch为字符,则regex的值为”|”。Stringsubstring(intbeginI

128、ndex,intendIndex):返回一个新字符串,它是此字符串指定位置beginindex开始到endindex位置的字符串,如果省略则表示到最后位置的字符串。StringtoLowerCase()使用默认语言环境的规则将此String中的所有字符都转换为小写。StringtoUpperCase():使用默认语言环境的规则将此String中的所有字符都转换为大写。Stringtrim():返回字符串的副本,忽略前导空白和尾部空白。staticString valueOf(Typex):返回Type类型的参数x的字符串表示形式。其中x可以是boolean、char、char、double、f

129、loat、int、long、Object等。String类例如、Stringaa=aaaa|bbbb|cccc.split(|);这是错误的,应该写成下面的语句:Stringaa=aaaa|bbbb|cccc.split(|);例如,Strings1,s2;s1=”abcdef”.substring(2);/则s1等于”cdef”;s2=”abcdef”.substring(2,2);/则s1等于”cd”;例如,将字符串bs,若干个空格字符作为分隔字符串。Stringbs=thisisasplitexample.;StringarrayStr=bs.split(s+);String类例7-2输

130、入字符串,判断该字符串由多少个单词构成,单词之间用指定分隔符分隔。1publicclassSplitTest2publicstaticvoidmain(Stringargs)3Stringwords;4Stringlines;5Scannersc=newScanner(System.in);6System.out.print(输入分隔符输入分隔符(只输入一个字符只输入一个字符,例如,例如,|,-,空格等空格等):);7chs=sc.nextLine();/输入一个字符输入一个字符8System.out.print(输入一个字符串输入一个字符串,各单词之间用各单词之间用|分隔。分隔。);9lin

131、es=sc.nextLine();/输入一个字符串输入一个字符串10words=lines.split(+chs);11System.out.println(单词的个数单词的个数=+words.length);12for(Stringa:words)13System.out.print(a+t);1415String类例7-3输入字符串,该字符串是简单的算术表达式(假定只能进行加、减、乘、除运算),然后依据该表达式,计算结果,其算法如图7-1所示。String类1publicclassCompute2publicstaticvoidmain(Stringargs)3StringopChars=

132、+-*/;4Scannersc=newScanner(System.in);5System.out.print(输入算术字符串输入算术字符串(形如形如aOb,其中字符其中字符O可以是可以是+、-、*、/):);6Stringlines=sc.nextLine();7charch1;/保存运算符字符串保存运算符字符串8Stringwords=;/保存两个操作数保存两个操作数9booleanflag=false;/flag为为false表示不能计算表示不能计算,flag为为true表示可以计算了。表示可以计算了。10doublea,b,s;/a,b分别保存两个操作数,而分别保存两个操作数,而s保存

133、算式运算的结果保存算式运算的结果11inti;12ch1=+;13/下面循环找到运算的操作符下面循环找到运算的操作符14for(i=0;ic,b-d,-,y-a,z-b,A-C,B-D,Y-A,Z-B。随后,又将该密文解密,得到明文。StringBuffer类1publicclassEncrypt2/加密方法加密方法3publicstaticvoidencrypt(StringBuffers,intn)4inti;5charch,ch1;6charstartChar=A;7for(i=0;i=a&ch=A&ch=a&ch=z)12startChar=a;ch1=(char)(ch-32);/将

134、将ch转换成大写字母转换成大写字母1314ch=(char)(startChar+(ch1-A+n)%26);15s.setCharAt(i,ch);161718StringBuffer类19/解密方法20publicstaticvoiddecrypt(StringBuffers,intn)21inti;22charch,ch1;23charstartChar=A;24for(i=0;i=a&ch=A&ch=a&ch=z)29startChar=a;30ch1=(char)(ch-32);3132ch=(char)(startChar+(ch1-A-n+26)%26);33s.setCharA

135、t(i,ch);343536返回目录7.3正则表达式正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符及这些特定字符的组合,组成一种规则字符串,该规则字符串可用来过滤字符串。正则表达式是一种文本模式,该模式描述在搜索文本时要匹配一个或多个字符串。字符普通字符特殊字符限定符定位符可打印字符不可打印字符正则表达式相关知识非打印字符对应的转义序列如下表所示。转义字符转义字符表示字符表示字符cx匹配由匹配由x指明的控制字符。例如,指明的控制字符。例如,cM匹配一个匹配一个Control-M或回车符。或回车符。x的的值必须为值必须为A-Z或或a-z之一。否则,将之一。否则,将c视为一

136、个原义的视为一个原义的c字符。字符。f 匹配一个换页符。等价于匹配一个换页符。等价于x0c和和cL。n 匹配一个换行符。等价于匹配一个换行符。等价于x0a和和cJ。r 匹配一个回车符。等价于匹配一个回车符。等价于x0d和和cM。s匹配任何空白字符,包括空格、制表符、换页符等等。等价于匹配任何空白字符,包括空格、制表符、换页符等等。等价于fnrtv。S 匹配任何非空白字符。等价于匹配任何非空白字符。等价于fnrtv。t 匹配一个制表符。等价于匹配一个制表符。等价于x09和和cI。v 匹配一个垂直制表符。等价于匹配一个垂直制表符。等价于x0b和和cK。正则表达式相关知识特殊字符是指一些具有特殊含义

137、的字符,各特殊字符代表的意义如下表所示。符号符号特殊含义特殊含义*匹配前面的子表达式零次或多次。要匹配匹配前面的子表达式零次或多次。要匹配*字符,请使用字符,请使用*。+匹配前面的子表达式一次或多次。要匹配匹配前面的子表达式一次或多次。要匹配+字符,请使用字符,请使用+。.匹配除换行符匹配除换行符n之外的任何单字符。要匹配之外的任何单字符。要匹配.,请使用,请使用.。标记一个中括号表达式的开始。要匹配标记一个中括号表达式的开始。要匹配,请使用,请使用。?匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配?字符,字符,请使用请

138、使用?。将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如,例如,n匹配字符匹配字符n。n匹配换行符。序列匹配换行符。序列匹配匹配,而,而(则匹配则匹配(。匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配该字符集合。要匹配字符本身,请使用字符本身,请使用。标记限定符表达式的开始。要匹配标记限定符表达式的开始。要匹配,请使用,请使用。|指明两项之间的一个选择。要匹配指明两项之间的一个选择。要匹配|,

139、请使用,请使用|。正则表达式相关知识限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。符号符号说明说明*匹配前面的子表达式零次或多次。例如,匹配前面的子表达式零次或多次。例如,fo*能匹配能匹配fo、foo等。等。*等价于等价于0,。+匹匹配配前前面面的的子子表表达达式式一一次次或或多多次次。例例如如,fo+可可以以匹匹配配fo以以及及foo,但但不不能能匹匹配配z。+等价于等价于1,。?匹配前面的子表达式零次或一次。例如,匹配前面的子表达式零次或一次。例如,do(es)?能匹配能匹配do、does?等价于等价于0,1。nn是是一一个个非非负负整整数数。匹匹配配确确定定的的n

140、次次。例例如如,o2不不可可匹匹配配Bob中中的的o,但但是是能能匹匹配配good中的两个中的两个o。n,n是是一一个个非非负负整整数数。至至少少匹匹n次次。例例如如,e2,不不可可匹匹配配e中中的的o,但但能能匹匹配配geeeed中的所有中的所有o。o1,等价于等价于o+。o0,则等价于则等价于o*。n,mm和和n均均为为非非负负整整数数,其其中中n=m。最最少少匹匹配配n次次且且最最多多匹匹配配m次次。例例如如,o1,4将将匹匹配配zooooood中中的的前前四四个个o。o0,1等等价价于于o?。请请注注意意在在逗逗号号和和两两个个数数之之间间不不能能有空格。有空格。正则表达式相关知识定位

141、符能够将正则表达式固定到行首或行尾。它们还能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。正则表达式的定位符如右表所示。定位定位符符意义意义匹配输入字符串开始的位置。如果设置了匹配输入字符串开始的位置。如果设置了RegExp对象的对象的Multiline属性,属性,还会与还会与n或或r之后的位置匹配。之后的位置匹配。$匹配输入字符串结尾的位置。如果设置了匹配输入字符串结尾的位置。如果设置了RegExp对象的对象的Multiline属性,属性,$还会与还会与n或或r之前的位置匹配。之前的位置匹配。b匹配一个字边界,即字与空格间的位置。匹配一个字边界,

142、即字与空格间的位置。B非字边界匹配。非字边界匹配。d匹配一个数字字符,等价于匹配一个数字字符,等价于0-9。D匹配一个非数字字符,等价于匹配一个非数字字符,等价于0-9。w匹配包括下划线的任何单词字符。类似但不等价于匹配包括下划线的任何单词字符。类似但不等价于A-Za-z0-9_,这里的单词字符是,这里的单词字符是Unicode字符。字符。W匹配任何非单词字符。等价于匹配任何非单词字符。等价于A-Za-z0-9_。xn匹匹配配n,其其中中n为为十十六六进进制制转转义义值值。十十六六进进制制转转义义值值必必须须为为确确定定的的两两个个数数字字长长。例例如如,x41匹匹配配A。x041则等价于则等

143、价于x04&1。正则表达式中可以使用。正则表达式中可以使用ASCII编码。编码。num匹配匹配num,其中,其中num是一个正整数。对所获取的匹配的引用。例如,是一个正整数。对所获取的匹配的引用。例如,(.)1匹配两个连续的相同字符。匹配两个连续的相同字符。n标标识识一一个个八八进进制制转转义义值值或或一一个个向向后后引引用用。如如果果n之之前前至至少少n个个获获取取的的子子表表达达式式,则则n为为向向后后引引用用。否否则则,如果如果n为八进制数字(为八进制数字(0-7),则),则n为一个八进制转义值。为一个八进制转义值。nm标标识识一一个个八八进进制制转转义义值值或或一一个个向向后后引引用用

144、。如如果果nm之之前前至至少少有有nm个个获获得得子子表表达达式式,则则nm为为向向后后引引用用。如如果果nm之之前前至至少少有有n个个获获取取,则则n为为一一个个后后跟跟文文字字m的的向向后后引引用用。如如果果前前面面的的条条件件都都不不满满足足,若若n和和m均为八进制数字(均为八进制数字(0-7),则),则nm将匹配八进制转义值将匹配八进制转义值nm。nml如果如果n为八进制数字(为八进制数字(0-7),且),且m和和l均为八进制数字(均为八进制数字(0-7),则匹配八进制转义值),则匹配八进制转义值nml。匹匹配配词词(word)的的开开始始()。例例如如正正则则表表达达式式能能够够匹匹

145、配配字字符符串串forthewise中中的的the,但是不能匹配字符串,但是不能匹配字符串otherwise中的中的the。注意:这个元字符不是所有的软件都支持的。注意:这个元字符不是所有的软件都支持的。Java语言处理正则表达式在Java.util.regex包中,Java定义了Pattern、Matcher两个重要类来处理正则表达式。其中Pattern类用于匹配字符序列与正则表达式指定模式的类。Pattern类指定为字符串的正则表达式必须首先被编译为此类的实例。Matcher类是通过解释Pattern对字符序列执行匹配操作的引擎。Java语言处理正则表达式1.Pattern类Pattern

146、对象指定为字符串的正则表达式必须首先被编译为Pattern类的实例。Pattern类的主要方法如下:staticPatterncompile(Stringregex)将给定的正则表达式编译到模式中。staticPatterncompile(Stringregex,intflags)将给定的正则表达式编译到具有给定标志的模式中。intflags()返回此模式的匹配标志。Matchermatcher(CharSequenceinput)创建匹配给定输入与此模式的匹配器。staticbooleanmatches(Stringregex,CharSequenceinput)编译给定正则表达式并尝试将给

147、定输入与其匹配。Stringpattern()返回在其中编译过此模式的正则表达式。staticStringquote(Strings)返回指定String的字面值模式String。Stringsplit(CharSequenceinput)围绕此模式的匹配拆分给定输入序列。Stringsplit(CharSequenceinput,intlimit)围绕此模式的匹配拆分给定输入序列。Java语言处理正则表达式Matcher类是通过解释Pattern对字符序列执行匹配操作的引擎。Matcher类的主要方法有:StringBufferappendTail(StringBuffersb)实现终端追加

148、和替换步骤。intend()返回最后匹配字符之后的偏移量。intend(intgroup)返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。booleanfind()尝试查找与该模式匹配的输入序列的下一个子序列。booleanfind(intstart)重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。Stringgroup()返回由以前匹配操作所匹配的输入子序列。Stringgroup(intgroup)返回在以前匹配操作期间由给定组捕获的输入子序列。intgroupCount()返回此匹配器模式中的捕获组数。booleanhitEnd()如果

149、匹配器执行的最后匹配操作中搜索引擎遇到输入结尾,则返回true。booleanlookingAt()尝试将从区域开头开始的输入序列与该模式匹配。booleanmatches()尝试将整个区域与模式匹配。Java语言处理正则表达式Patternpattern()返回由此匹配器解释的模式。staticStringquoteReplacement(Strings)返回指定String的字面值替换String。Matcher region(intstart,intend)设置此匹配器的区域限制。intregionEnd()报告此匹配器区域的结束索引(不包括)。intregionStart()报告此匹配

150、器区域的开始索引。StringreplaceAll(Stringreplacement)替换模式与给定替换字符串相匹配的输入序列的每个子序列。StringreplaceFirst(Stringreplacement)替换模式与给定替换字符串匹配的输入序列的第一个子序列。boolean requireEnd()如果很多输入都可以将正匹配更改为负匹配,则返回true。Matcher reset()重置匹配器。Matcher reset(CharSequenceinput)重置此具有新输入序列的匹配器。intstart()返回以前匹配的初始索引。intstart(intgroup)返回在以前的匹配操

151、作期间,由给定组所捕获的子序列的初始索引。Java语言处理正则表达式使用正则表达式的步骤如下:(1)根据需要,设计好正则表达式字符串str。(2)调用Pattern类的静态方法compile(str)方法,得到Pattern类的实例p。(3)然后调用p对象的matcher(str)方法,得到Matcher对象matcher。(4)当执行对象matcher的find()方法,如果匹配成功,则输出匹配的子序列。根据该序列做相应的处理操作。(5)重复(4)操作,直到不能匹配,就结束。Java语言处理正则表达式例7-5计算字符串中各课成绩的平均分。1publicclassRegex12publicst

152、aticvoidmain(Stringargs)3Stringstr=计算机计算机:86.5,大学英语大学英语:79,数据结构数据结构:80,大学语文,大学语文:80;4Stringregex=0123456789+.0,10123456789+;5Patternpattern=Ppile(regex);6Matchermatcher=pattern.matcher(str);7doubles=0;8intcount=0;9while(matcher.find()/查找与模式匹配的输入序列的下一个子序列查找与模式匹配的输入序列的下一个子序列10Stringt=matcher.group();/

153、得到匹配的输入子序列得到匹配的输入子序列11s=s+Double.parseDouble(t);12count+;1314s=s/count;15System.out.println(平均分平均分=+s);1617Java语言处理正则表达式例7-6从字符串中检测出所有合法的手机电话号码。1publicclassRegetTelephone2publicstaticvoidmain(Stringargs)3Stringstr=18971612345,15087654321,13912345678,139131,68932,232332232;4Stringregex=(130-9|150|1|2

154、|3|5|6|7|8|9|180|1|2|3|5|6|7|8|9)d8;5Patternpattern=Ppile(regex);6Matchermatcher=pattern.matcher(str);7doubles=0;8intcount=0;9while(matcher.find()/查找与模式匹配的输入序列的下一个子序列查找与模式匹配的输入序列的下一个子序列10Stringt=matcher.group();/得到匹配的输入子序列得到匹配的输入子序列11System.out.println(t);121314返回目录7.4基本数据类型的包装类基本数据类型基本数据类型包装类包装类基本数

155、据类型基本数据类型包装类包装类byteByteintIntegerbooleanBooleanlongLongshortShortfloatFloatcharCharacterdoubleDouble在Cname类中主要方法如下:intcompareTo(CnameanotherCname)从数字上比较两个Cname对象。StaticCnameparseCname(Strings)返回一个新的name值,该值被初始化为用指定String表示的值,这与Cname类的valueOf方法产生的值类似。staticCnamevalueOf(cnamed)返回表示指定的基本数据类型cname值的Cnam

156、e实例。staticCnamevalueOf(Strings)返回保持用参数字符串s表示的基本数据类型cname值的Cname对象。cnameValue()返回此Cname对象的cname值。返回目录基本数据类型的包装类例7-8输入三角形的三条边a,b,c数据以逗号分隔,求三角形的面积。1publicclassArea2publicstaticvoidmain(Stringargs)3Stringline;4Scannersc=newScanner(System.in);5System.out.println(输入三角形的三条边长输入三角形的三条边长(以逗号分隔数据以逗号分隔数据,假定输入的数

157、据构成三角形假定输入的数据构成三角形);6line=sc.nextLine();7Stringdata=line.split(,);8doublea=Double.parseDouble(data0);/从字符串中解析出边长从字符串中解析出边长a9doubleb=Double.parseDouble(data1);/从字符串中解析出边长从字符串中解析出边长b10doublec=Double.parseDouble(data2);/从字符串中解析出边长从字符串中解析出边长c11doubles,p=(a+b+c)/2;12s=Math.sqrt(p*(p-a)*(p-b)*(p-c);13Syst

158、em.out.println(三角形的面积三角形的面积=+s);14157.5Object类Object类的主要方法如下:protectedObjectclone()创建并返回此对象的一个副本。boolean equals(Objectobj)指示某个其他对象是否与此对象“相等”。ClassgetClass()返回一个对象的运行时类。voidnotify()唤醒在此对象监视器上等待的单个线程。voidnotifyAll()唤醒在此对象监视器上等待的所有线程。StringtoString()返回该对象的字符串表示。很多情况下,需要重载toString()方法。这样得到应该自己所需的类对象字符串表

159、示。1publicclassSphereimplementsCloneable/实现实现Cloneable接口接口2finalstaticdoublePI=3.14159;/定义常量定义常量3privatedoubler;4publicSphere(doubler)5this.r=r;67publicdoublegetArea()8doubles;9s=4*PI*r*r;10returns;1112publicvoidsetR(doubler)13this.r=r;1415publicdoublegetVolume()16doublev;17v=4.0/3.0*PI*r*r*r;18retur

160、nv;1920Override21publicStringtoString()22return球球t+半径半径r=+r+t表面积表面积s=+getArea()+t体积体积=+getVolume();23Object类Object类24publicstaticvoidmain(Stringargs)throwsCloneNotSupportedException25Sphereb1=newSphere(2.0);26System.out.println(b1.getClass();27Sphereb2=(Sphere)b1.clone();28System.out.println(b1.toSt

161、ring()=+b1.toString();29System.out.println(b1=+b1);30System.out.println(b2=+b2);31b2.setR(3);/修改修改b2的半径的半径32System.out.println(b1=+b1);33System.out.println(b2=+b2);/注意此处输出注意此处输出34Sphereb3=newSphere(2.0),b4;35b4=b3;/b4是是b3的引用的引用36System.out.println(b3=+b3);37System.out.println(b4=+b4);38System.out.pr

162、intln(b1=b2:+b1.equals(b2);/b1和和b2不是指向同一对象不是指向同一对象39System.out.println(b1=b3:+b1.equals(b3);40System.out.println(b3=b4:+b3.equals(b4);41b3.setR(4);/修改修改b3对象的半径,观察对象的半径,观察b3和和b4的情况的情况42System.out.println(b3=+b3);43System.out.println(b4=+b4);44457.6Math类Math类中常用的主要方法如下:Math类Math类1publicclassMathTest12

163、publicstaticdoubleln(doublex)3returnMath.log(x);45publicstaticvoidmain(Stringargs)6doublea=Math.PI/5,v1;7doublex=5,v2,v3;8v1=3*Math.tan(a)-4*Math.pow(Math.sin(a),3);910v2=ln(x+Math.sqrt(x*x+1);11v3=ln(x)/ln(6);12System.out.println(v1=+v1);13System.out.println(v2=+v2);14System.out.println(v3=+v3);151

164、6Math类例7-11输入a,b两个整数(要求ba),求产生若干个值在指定区间(a,b)的随机整数。1publicclassMathTest22publicstaticvoidmain(Stringargs)3doublex,value;4inta,b,num;5Scannersc=newScanner(System.in);6System.out.println(输入输入a,b两个整数(要求两个整数(要求ba);7System.out.print(输入输入a:);8a=sc.nextInt();9System.out.print(输入输入b:);10b=sc.nextInt();11whil

165、e(b0):);18num=sc.nextInt();19intcount=0;20while(countnum)21x=Math.random();/Math.random()方法产生值在范围方法产生值在范围(0,1)22value=a+(b-a)*x;23if(count%10=0&count!=0)/一行最多输出一行最多输出10个数个数24System.out.println();/换行换行25System.out.printf(%.1ft,value);/小数部分保留小数部分保留1位位26count+;2728System.out.println();2930本章结束!第8章抽象类和接

166、口本章内容8.1抽象类的概念8.2接口概念8.2.1接口定义8.2.2接口的实现8.3枚举类Enum8.3.1为什么需要枚举类型8.3.2定义枚举类型8.3.3自定义枚举类型8.1抽象类的概念在面向对象领域由于抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能实例化的。同时,抽象类体现了数据抽象的思想,是实现多态的一种机制。它定义了一组抽象方法,至于这组抽象方法的具体实现有子类来实现。抽象方法的声明格式为:abstract返回值类型方法名称(参数列表);抽象类的概念在Java语言中,抽象类的定义如下:访问权限修饰符abstractclass抽象类名字abstract返回

167、值类型方法名称1(参数列表);抽象类和普通类的主要以下几点区别抽象类和普通类的主要以下几点区别:(1)抽象方法必须为抽象方法必须为public或者或者protected(如果为(如果为private,则不能被子类继,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为承,子类便无法实现该方法),缺省情况下默认为public;(2)如果一个类继承于一个抽象类,则子类必须实现父类的所有抽象方法。如果一个类继承于一个抽象类,则子类必须实现父类的所有抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为如果子类没有实现父类的抽象方法,则必须将子类也定义为abstract类类;(3)抽象类

168、不能实例化,而非抽象类可以实例化。抽象类不能实例化,而非抽象类可以实例化。抽象类的概念例8-1定义了Person类、Student类以及Teacher类,它们的类继承关系如下图所示。抽象类的概念1abstractpublicclassPerson2Stringid;/身份证编号3Stringname;/姓名4publicPerson(Stringid,Stringname)5this.id=id;6this.name=name;78Override9publicStringtoString()10return我的有关信息:身份证编号是+id+,姓名是+name;1112/抽象方法,没有具体的实

169、现,Person的子类中必须实现该方法。13publicabstractvoidwork();14抽象类的概念1publicclassStudentextendsPerson2Stringno;/学号学号3Stringmajor;/所学专业所学专业4publicStudent(Stringno,Stringmajor,Stringid,Stringname)5super(id,name);6this.no=no;7this.major=major;89Override10publicStringtoString()11returnsuper.toString()+,我的学号,我的学号+no+,

170、主修主修+major;1213Override14publicvoidwork()15System.out.println(我的工作就是学习我的工作就是学习);1617publicstaticvoidmain(Stringargs)18Studentt=newStudent(1001,计算机计算机,360001,张三张三);19System.out.println(t);20t.work();2122抽象类的概念1publicclassTeacherextendsPerson2Stringtno;/工号工号3Stringcourse;/授课列表授课列表4publicTeacher(String

171、id,Stringname,Stringtno,Stringcourse)5super(id,name);6this.tno=tno;7this.course=newStringcourse.length;8inti;9for(i=0;icourse.length;i+)10this.coursei=newString(coursei);1112publicStringtoString()13Stringmsg=;14inti;15for(i=0;icourse.length;i+)1617if(i=0)18msg=msg.concat(coursei);19else20msg=msg.con

172、cat(,+coursei);2122returnsuper.toString()+,我的工号是,我的工号是+tno+,我教授课程有:我教授课程有:+msg;2324Override25publicvoidwork()26System.out.println(我的工作就是教书我的工作就是教书);27抽象类的概念例8-2定义抽象类Animal,以及具体实现类(母鸡类Hen和狗类Dog),它们的类继承关系如下图所示。抽象类的概念1abstractpublicclassAnimal2Stringname;/动物名称动物名称3intnumOfLeg;/腿的数量腿的数量4doubleweight;/平均

173、体重平均体重5publicAnimal(Stringname,intnumOfLeg,doubleweight)6this.name=name;7this.numOfLeg=numOfLeg;8this.weight=weight;910Override11publicStringtoString()12return动物基本情况动物基本情况:+name+,腿的数量是:腿的数量是:+numOfLeg+,平均体重平均体重+weight+公斤公斤;1314/喜欢食物的方法喜欢食物的方法15publicabstractvoidfavoriteFood();16/叫声的方法叫声的方法17abstract

174、publicvoidshout();18/技能方法技能方法19abstractpublicvoidskill();20抽象类的概念1publicclassHenextendsAnimal2/默认构造方法默认构造方法3publicHen()4super(母鸡母鸡,2,2);/调用父类构造方法调用父类构造方法56Override7/喜欢食物方法喜欢食物方法8publicvoidfavoriteFood()9System.out.println(母鸡爱吃的食物有:谷子,虫母鸡爱吃的食物有:谷子,虫,草籽等。草籽等。);1011Override12/叫声方法叫声方法13publicvoidshout(

175、)14System.out.println(母鸡叫声是母鸡叫声是:咯咯,特别当它下完蛋时,喜欢咯咯的叫。咯咯,特别当它下完蛋时,喜欢咯咯的叫。);1516Override17publicvoidskill()18System.out.println(我的本领是每天下又大又新鲜的鸡蛋。我的本领是每天下又大又新鲜的鸡蛋。);19抽象类的概念1publicclassDogextendsAnimal2/默认构造方法默认构造方法3publicDog()4super(狗狗,4,24);/调用父类构造方法调用父类构造方法56Override7publicvoidfavoriteFood()8System.o

176、ut.println(狗爱吃的食物有狗爱吃的食物有:肉肉,骨头。骨头。);910Override11publicvoidshout()12System.out.println(狗叫声是狗叫声是:汪汪。特别当它看见陌生人时,喜欢汪汪的叫。汪汪。特别当它看见陌生人时,喜欢汪汪的叫。);1314Override15publicvoidskill()16System.out.println(我的本领是帮主人看家。我的本领是帮主人看家。);1718publicstaticvoidmain(Stringargs)19Dogd=newDog();20System.out.println(d);21d.fav

177、oriteFood();22d.shout();2324返回目录8.2接口定义在Java语言中,是通过使用interface来定义接口的。在接口定义中,编程者主要工作就是定义若干个常量以及一些方法。其定义形式如下:访问权限修饰符interface接口名称extends父接口名称表publicstaticfinal数据成员名称;publicabstract方法名称;接口定义在定义接口时,需要注意以下几点:(1)一般情况下,接口名称要满足标识符的命名规则,而且接口名称的首一般情况下,接口名称要满足标识符的命名规则,而且接口名称的首字母一般要求是大写。字母一般要求是大写。(2)extends关键字是

178、可选项,它主要作用是指定父接口。一个类有且只有关键字是可选项,它主要作用是指定父接口。一个类有且只有一个父类,但一个接口可以有多个父接口。而且父接口列表说明有父接一个父类,但一个接口可以有多个父接口。而且父接口列表说明有父接口有那些接口组成,而且父接口列表中的各接口之间用逗号分隔。口有那些接口组成,而且父接口列表中的各接口之间用逗号分隔。(3)由于接口主要包括若干常量和若干方法的定义由于接口主要包括若干常量和若干方法的定义,所以其数据成员都是所以其数据成员都是publicstatic类型的,如果省略类型的,如果省略publicstatic两个关键字,则系统自动添加两个关键字,则系统自动添加这两

179、个修饰符。这两个修饰符。(4)在接口定义中,只需要书写方法的声明,不需要写具体方法的方法体。在接口定义中,只需要书写方法的声明,不需要写具体方法的方法体。(5)接口不像类那样有构造方法,如果有构造方法就是错误的;另外,接接口不像类那样有构造方法,如果有构造方法就是错误的;另外,接口亦不能被实例化。口亦不能被实例化。(6)同同Java的类文件相同,接口文件的文件名一定要跟接口名相同。的类文件相同,接口文件的文件名一定要跟接口名相同。(7)访问权限修饰符是可选项,主要用于规定接口的访问权限,可以定义访问权限修饰符是可选项,主要用于规定接口的访问权限,可以定义public或者默认权或者默认权。接口定

180、义例8-3对于银行各种业务,可以定义银行接口BankInterface。publicinterfaceBankInterfacepublicfloatdrawMoney(StringcardId,floatm);/取钱业务取钱业务publicvoidsaveMoney(floatm,StringcardId);/存钱业务存钱业务publicvoidprintCurrentAccount(StringcardId);/打印资金流水账业务打印资金流水账业务publicStringdispatchCard(Stringid);/发行银行卡发行银行卡publicvoidbuyFiancialProdu

181、ct(floatm,Stringid);/卖理财产品卖理财产品publicfloatreturnFiancialProduct(Stringid);/赎回理财产品赎回理财产品接口定义例8-4平面图形需要求得面积。于是,可以定义图形接口FigureInterface如下:publicinterfaceFigureInterfacepublicstaticdoublePi=3.14159;/定义常量定义常量publicdoublegetArea();/求图形面积求图形面积例8-5对于立体图形,不仅可以像平面图形那样求其表面积,它们还可以求体积。可以定义立体接口SolidFigureInterfac

182、e。publicinterfaceSolidFigureInterfaceextendsFigureInterfacepublicdoublegetVolume();/求立体图形的体积求立体图形的体积返回目录8.2.2接口的实现在Java语言中,主要是利用关键字implements来实现接口的。接口实现的一般形式如下:接口的实现例8-6下面定义三角形类Triangle,其定义形式如下。1publicclassTriangleimplementsFigureInterface2privatedoublea,b,c;/三角形的三条边长。三角形的三条边长。3Triangle(doublea,doub

183、leb,doublec)4this.a=a;5this.b=b;6this.c=c;78publicStringtoString()9returnt边长边长a=+a+t边长边长b=+b+t边长边长c=+c+t面积面积s=+getArea();1011publicdoublegetArea()/接口中的方法实现接口中的方法实现12doublep,s;13p=(a+b+c)/2.0;14s=Math.sqrt(p*(p-a)*(p-b)*(p-c);15returns;1617publicstaticvoidmain(Stringargs)18Trianglet=newTriangle(3,4,5

184、);19System.out.println(t);2021接口的实现例8-7圆柱体图形如下图所示。定义圆柱体Cylinder类,该类实现立方图形SolidFigureInterface接口。1publicclassCylinderimplementsSolidFigureInterface2privatedoubler;/圆柱体的半径圆柱体的半径3privatedoubleh;/圆柱体的高圆柱体的高4Cylinder(doubler,doubleh)5this.r=r;6this.h=h;78Override9publicStringtoString()10return圆柱体信息:圆柱体信息

185、:+半径是半径是+r+,高是:高是:+h+,表面表面积积=+getArea()+,体积体积=+getVolume();1112/接口中的方法实现接口中的方法实现,求圆柱体的表面积求圆柱体的表面积13publicdoublegetArea()14doubles;15s=2*r*PI*h+r*r*PI*2;16returns;1718/接口中的方法实现接口中的方法实现,求圆柱体的体积求圆柱体的体积19publicdoublegetVolume()20doublev;21v=r*r*PI*h;22returnv;2324接口的实现对于在接口中声明的方法,在类实现接口时,必须都必须实现这些方法。但是,

186、很多时候,只关心接口中的个别方法,不想实现接口中的其它方法,这是应该怎么办?可以先定义一个抽象类,该抽象类实现这些方法,并且这些方法的方法体部可以先定义一个抽象类,该抽象类实现这些方法,并且这些方法的方法体部分是空的,没有什么具体内容。而由该抽象类派生而来的类,就可以实现接分是空的,没有什么具体内容。而由该抽象类派生而来的类,就可以实现接口中的个别方法,而不去实现其它的方法。口中的个别方法,而不去实现其它的方法。接口的实现例8-8定义图形接口FigureInterface1,该接口多一个方法publicdoublegetPerimeter(),该方法功能是图形周长。publicinterfac

187、eFigureInterface1publicstaticdoublePI=3.14159;publicdoublegetArea();/求图形面积求图形面积publicdoublegetPerimeter();/得到图形周长得到图形周长publicabstractclassFigureInterfaceAdapterimplementsFigureInterface1publicdoublegetArea()return0.0;publicdoublegetPerimeter()return0.0;publicvoidprint()接口的实现例8-9定义圆柱体类Cylinder1。1publ

188、icclassCylinder1extendsFigureInterfaceAdapter2privatedoubler;/圆柱体的半径圆柱体的半径3privatedoubleh;/圆柱体的高圆柱体的高4Cylinder1(doubler,doubleh)5this.r=r;6this.h=h;78Override9publicStringtoString()10return圆柱体信息:圆柱体信息:+半径是半径是+r+,高是:高是:+h+,表面积表面积=+getArea()+,体积体积=+getVolume();1112/接口中的方法实现接口中的方法实现,求圆柱体的表面积求圆柱体的表面积13p

189、ublicdoublegetArea()14doubles;15s=2*r*PI*h+r*r*PI*2;16returns;1718/接口中的方法实现接口中的方法实现,求圆柱体的体积求圆柱体的体积19publicdoublegetVolume()20doublev;21v=r*r*PI*h;22returnv;2324Cylinder1没有没有实现实现接口中接口中的的实现实现接口中接口中的的getPerimeter(),返回目录8.3枚举类Enum在JDK1.5之前,类或者接口定义常量的方法是:publicstaticfinal变量名。在很多时候,这样一些简单常量满足程序需要。但是当程序复杂时

190、,它们显得可读性差。例8-10定义交通信号灯类TrafficLight,其中分别用RED、GREEN、YELLOW表示红、绿、黄。8.3.1为什么需要枚举类型例8-10定义交通信号灯类TrafficLight,其中分别用RED、GREEN、YELLOW表示红、绿、黄。1publicclassTrafficLight2publicfinalintGREEN=0;3publicfinalintRED=1;4publicfinalintYELLOW=2;5intlightState;6publicTrafficLight()7this.lightState=RED;/默认灯颜色是红色默认灯颜色是红色

191、89Override10publicStringtoString()11Stringmsg=;12switch(lightState)13caseGREEN:14msg=绿绿;break;15caseYELLOW:16msg=黄黄;break;17caseRED:18msg=红红;1920return灯:灯:+msg;2122/改变灯状态23publicvoidchange()24lightState=lightState+1;lightState=lightState%3;2526publicstaticvoidmain(Stringargs)27TrafficLightlight=newT

192、rafficLight();28inti;29for(i=0;i10;i+)30System.out.println(light);31light.change();3233341publicclassTrafficLight2publicfinalintGREEN=0;3publicfinalintRED=1;4publicfinalintYELLOW=2;5intlightState;6publicTrafficLight()7this.lightState=RED;/默认灯颜色是红色默认灯颜色是红色89Override10publicStringtoString()11Stringmsg

193、=;12switch(lightState)13caseGREEN:14msg=绿绿;break;15caseYELLOW:16msg=黄黄;break;17caseRED:18msg=红红;1920return灯:灯:+msg;2122/改变灯状态23publicvoidchange()24lightState=lightState+1;lightState=lightState%3;2526publicstaticvoidmain(Stringargs)27TrafficLightlight=newTrafficLight();28inti;29for(i=0;i10;i+)30Syste

194、m.out.println(light);31light.change();323334定义枚举类型Java语言定义枚举类型的方法如下:enum枚举类型名称 常量1,常量2,常量n;例如,星期的枚举类型WeekEnum可以定义如下:enumweekEnumSunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday;Java语言为枚举类型提供了如下主要方法:intordinal()返回枚举常量的序数(它在枚举声明中的位置,其中初始常量返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。序数为零)。Stringname()返回此枚

195、举常量的名称,在其枚举声明中对其进行声明。返回此枚举常量的名称,在其枚举声明中对其进行声明。boolean equals(Objectother)当指定对象等于此枚举常量时,返回当指定对象等于此枚举常量时,返回true。TEnumvalues()以数组的形式返回所有的枚举常量值以数组的形式返回所有的枚举常量值,TEnum是定义的枚举类型。是定义的枚举类型。8.3.2定义枚举类型例8-11关于枚举常量的例子:交通信号灯的颜色有:绿、红和黄。1enumLightColor绿绿,红红,黄黄2publicclassTrafficLight13LightColorlightState;4publicTr

196、afficLight1()5this.lightState=LightColor.红红;/默认灯颜色是红色默认灯颜色是红色67Override8publicStringtoString()9return当前灯颜色:当前灯颜色:+lightState.name();/得到枚举常量名称得到枚举常量名称1011/改变灯状态改变灯状态12publicvoidchange()13intorder=lightState.ordinal();/得到枚举常量的序数得到枚举常量的序数14LightColorlightColors=LightColor.values();/得到所有枚举常量得到所有枚举常量15or

197、der=(order+1)%lightColors.length;/得到枚举常量的个数得到枚举常量的个数16lightState=lightColorsorder;/17定义枚举类型18publicstaticvoidmain(Stringargs)19TrafficLight1light=newTrafficLight1();20inti;21for(i=0;i10;i+)2223System.out.println(light);24light.change();2526if(light.lightState.equals(LightColor.黄黄)27System.out.printl

198、n(现在灯颜色是:黄现在灯颜色是:黄);2829返回目录8.3.3自定义枚举类型自定义枚举类型方法如下:publicenum枚举类型名称枚举常量1(“枚举常量1的说明部分”,序号1),枚举常量2(“枚举常量2的说明部分”,序号2),枚举常量2(“枚举常量2的说明部分”,序号n);/Stringname;/枚举常量的说明部分Stringorder;/序号自定义枚举类型例8-12定义一个图形枚举类型FigureEnum,它有三个枚举常量TRIANGLE、RECTANGLE和CIRCLE,它们分别代表三角形、长方形、圆形。1importjava.util.Random;2publicenumFigu

199、reEnum3TRIANGLE(三角形三角形,0),RECTANGLE(矩形矩形,1),CIRCLE(圆形圆形,2);4Stringdescription;/枚举常量的说明部分枚举常量的说明部分5intorder;/枚举常量的序号枚举常量的序号6privateFigureEnum(Stringdescription,intorder)7this.description=description;8this.order=order;910publicStringgetDescription()11returndescription;1213publicvoidsetOrder(intorder)1

200、4this.order=order;1516publicvoidsetDescription(Stringdescription)17this.description=description;18自定义枚举类型19publicStringgetDescription(intorder)20for(FigureEnumf:FigureEnum.values()21if(f.getOrder()=order)22returnf.getDescription();2324returnnull;2526Override27publicStringtoString()28returnname()+(+d

201、escription+,+order+);2930/得到随机序号,通过随机序号来返回相应的枚举常量得到随机序号,通过随机序号来返回相应的枚举常量31publicstaticFigureEnumgetRandomFigureEnum()32intorder1;33Randomrand=newRandom();34order1=rand.nextInt(FigureEnum.values().length);35FigureEnumfes=FigureEnum.values();36returnfesorder1;3738publicintgetOrder()39returnorder;4041自

202、定义枚举类型例8-13测试枚举类型文件TestFigureEnum.java。1publicclassTestFigureEnum2publicstaticvoidmain(Stringargs)3FigureEnumtype;/定义一枚举类型变量定义一枚举类型变量4for(inti=0;i10;i+)5type=FigureEnum.getRandomFigureEnum();/得到随机枚举类型的随机值得到随机枚举类型的随机值6switch(type)7caseTRIANGLE:8System.out.println(输入三角形数据输入三角形数据);break;9caseRECTANGLE:

203、10System.out.println(输入长方形数据输入长方形数据);break;11caseCIRCLE:System.out.println(输入长方形数据输入长方形数据);12break;13141516本章结束!第9章泛型和反射本章内容9.1泛型9.1.1泛型概念9.1.2泛型定义9.1.3、和9.2常用泛型接口和类9.2.1常用泛型接口9.2.2常用泛型类9.3反射9.3.1反射概念9.3.2与反射相关的类9.1泛型概念例9-1利用链表类保存数据的例子。1importjava.util.ArrayList;2publicclassListTest3publicstaticvoid

204、main(Stringargs)4ArrayListarrayList=newArrayList();/利用数组队列保持数据利用数组队列保持数据5arrayList.add(张三张三);/姓名姓名6arrayList.add(18);/年龄年龄7arrayList.add(女女);/姓名姓名8arrayList.add(80);/分数分数9arrayList.add(94);/分数分数10arrayList.add(90);/分数分数11Stringmsg;12for(inti=0;iarrayList.size();i+)13msg=(String)arrayList.get(i);14Sy

205、stem.out.println(msg);151617在哪一行,系统将报错?在哪一行,系统将报错?9.1.2泛型定义为解决上问题,Java语言提供了泛型。在Java语言中,泛型类定义如下:publicclass泛型类类名.;/相关代码声明泛型变量方法如下:泛型类类名变量名;泛型类类名变量名=new泛型类类名(参数列表);为泛型变量赋值的方法如下:变量名=new泛型类类名(参数列表);或者变量名=new泛型类类名(参数列表);泛型定义泛型接口定义如下:Publicinterface接口名publicvoid方法1(参数列表);publicT方法2(参数列表);v调用泛型方法如下:方法名(实参参

206、数列表);或变量=方法名(实参参数列表);v泛型方法定义如下:publicT方法名(参数列表).;/相关代码或者publicvoid方法名(参数列表).;/相关代码泛型定义-举例例9-2定义TestGenericFun,其内定义了泛型方法。1importjava.util.Date;2publicclassTestGenericFun3publicstaticvoidfun1(Tt)4System.out.println(fun1:+t);56publicstaticTfun2(Tt)7System.out.println(fun2:+t);8returnt;910publicstaticvo

207、idmain(Stringargs)11/调用泛型方法12fun1(string);13fun1(3.14159);14fun1(newDate();/15Stringmsg=fun2(abcdef);16System.out.println(msg);1718泛型定义-举例例9-3定义一泛型类Generic1。2publicclassGeneric13privateTdata;/属性属性data的数据类型是的数据类型是T4publicGeneric1(Tdata)5this.data=data;6714publicstaticvoidmain(Stringargs)15Generic1g1=

208、newGeneric1(张三张三);16System.out.println(g1);17Generic1g2=newGeneric1(18);18System.out.println(g2);19Generic1g3=newGeneric1(newDate();20System.out.println(g3);2122泛型定义-举例例9-4随机产生10个随机图形(此处,主要是指三角形和长方形)。(1)首先,定义一泛型接口首先,定义一泛型接口IProducer如下:如下:publicinterfaceIProducerpublicEnext();(2)然后定义类然后定义类ProduceFigu

209、re,该类实现了接口,该类实现了接口IProducer。泛型定义-举例1publicclassProduceFigureimplementsIProducer2Override3publicFigurenext()4Randomrand=newRandom();5intt=rand.nextInt(2);/产生6floata,b,c;7a=rand.nextFloat()*100;/随机得到边长8b=rand.nextFloat()*100;9Figuref;10if(t=0)/产生长方形11f=newRectangle(a,b);12else/否则产生三角形13c=rand.nextFloa

210、t()*100;/另外随机得到边长14f=newTriangle(a,b,c);1516returnf;17返回目录9.1.3、和publicclassFood1publicclassDrinkextendsFood2publicDrink()3Override4publicStringtoString()5return饮料;671publicclassMilkextendsDrink2Override3publicStringtoString()4return牛奶+(属于+super.toString()+);56、和1publicclassWineextendsDrink2Override

211、3publicStringtoString()4return酒+(属于+super.toString()+);561publicclassBowl2privateEthing;3publicBowl(Edrink)4this.thing=drink;56publicBowl()7this.thing=null;89publicEgetThing()10returnthing;1112publicvoidsetThing(Ething)13this.thing=thing;1415Override16publicStringtoString()17if(thing!=null)18return我

212、是一个碗+,装了+thing;19else20return我是一个碗,但没有装东西;2122下面语句是否正确?下面语句是否正确?Bowlbowl1;bowl1=newBowl(newMilk();、和,它表示所有由,它表示所有由T类继承过来的所有子类,同时还包括类继承过来的所有子类,同时还包括T。、和例9-5上界通配符的使用例子。1publicclassTestUpWildcards2publicstaticvoidmain(Stringargs)3Bowlbowl1=newBowl(newDrink();4System.out.println(bowl1);5/Bowlbowl2=newBo

213、wl(newMilk();该语句出现错误6Bowlbowl2=newBowl(newMilk();7System.out.println(bowl2);8Bowlbowl3=newBowl(newDrink();9System.out.println(bowl3);10bowl2=newBowl();/bow1的属性11System.out.println(bowl2);12Winewine1=newWine();13/bowl2.setThing(wine1);该语句有错误14wine1=(Wine)bowl3.getThing();/如果知道被取出对象的数据类型的话15System.out

214、.println(wine1);1617、和是指下界通配符(是指下界通配符(LowerBoundsWildcards),它是指),它是指T类或者类或者T类的父类的父类。类。、和可以指代任何类。对于类中声明了数据成员的数据类型是通配符规定的数据类型,可以是包括Object在内的所有类。例例9-7任意通配符?的使用任意通配符?的使用情况情况。1publicclassTestWildcards2publicstaticvoidmain(Stringargs)3Bowlbowl1=newBowl(newMilk();4System.out.println(bowl1);5Milkmilk1;6Obje

215、ctob;7milk1=(Milk)bowl1.getThing();/如果没有强制转换的话,将出错如果没有强制转换的话,将出错8Drinkdrink=(Drink)bowl1.getThing();/9System.out.println(drink);10ob=bowl1.getThing();11System.out.println(ob);12System.out.println(milk1);13milk1=newMilk();14/bowl1.setThing(milk1);该语句有错误该语句有错误1516、和例9-6下界通配符的使用例子如下。1publicclassTestLow

216、Wildcards2publicstaticvoidmain(Stringargs)3Bowlbowl1=newBowl(newMilk();4Milkmilk1=newMilk();5bowl1.setThing(milk1);/下界通配符可以6/milk1=bowl1.getThing();该语句有错误7System.out.println(bowl1);8bowl1=newBowl(newDrink();9System.out.println(bowl1);10bowl1=newBowl(newFood();11System.out.println(bowl1);12bowl1=newB

217、owl(newObject();13System.out.println(bowl1);1415返回目录9.2常用泛型接口和类常用泛型接口常用泛型接口和类1.Iterable接口Iterable接口允许对象成为foreach语句的目标。Iterable接口只定义了一个方法iterator(),该方法功能是:返回一个在一组T类型的元素上进行迭代的迭代器。2.Collection接口Collection接口是实现了集合操作的接口。3.Iterator接口Iterator接口是对集合进行迭代的迭代器,该接口的一个子接口有ListIterator接口。4.Map接口Map接口的作用:将键映射到值的对象

218、。5.Comparable接口Comparable接口是排序接口。若类实现了Comparable接口,则意味着该类支持排序。Comparable接口只定义了一个方法:intcompareTo(To)比较此对象与指定对象的顺序,比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。说明:对于自定义类,如果让类对象能够相互比较大小,则需要实现Comparable接口。常用泛型接口和类例9-8定义Product类,其属性包括(货号、供货商、品名、进价、零售单价、销量、利润),请按利润大小比较其商品价值大小,其中利润=(零售单价-进价)销量。1publiccla

219、ssProductimplementsComparable2Stringid;/货号3Stringproductor;/供货商4Stringname;/品名5doubleinPrice;/进价6doublesalePrice;/零售单价7doublevol;/销量8doubleprofit;/利润.29publicdoublegetProfit()30profit=(salePrice-inPrice)*vol;31returnprofit;3233publicintcompareTo(Objecto)34Productp=(Product)o;35intt=(int)(Math.signum

220、(this.getProfit()-p.getProfit();36returnt;3738publicstaticvoidmain(Stringargs)39Productp1,p2,p3;40p1=newProduct(692782928,汉批,男式西裤,75.60,108.00,212.00);.50System.out.println(p2-p1:+pareTo(p1);5152常用泛型类返回目录9.2.2常用泛型类ArrayListArrayList就是一动态数组类,每个ArrayList对象都有一个容量。该容量是指用来存储列表元素的数组的大小。它总是至少等于列表的大小。随着往Arr

221、ayList中不断添加元素,其容量也自动增长。ArrayList类的主要构造方法有:ArrayList()构造一个初始容量为10的空列表。ArrayList(intinitialCapacity)构造一个具有指定初始容量的空列表。例如,可以定义如下动态数组类对象:ArrayListarrayList=newArrayList();例9-9ArrayList类的使用举例。(ArrayListTest.java)常用泛型类-ArrayList举例1publicclassArrayListTest2publicstaticvoidmain(Stringargs)3ArrayListlist=newA

222、rrayList();/创建对象创建对象4list.add(张三张三);list.add(李四李四);list.add(王五王五);5list.add(赵七赵七);list.add(张三丰张三丰);list.add(万海涛万海涛);6System.out.println(添加元素之后:添加元素之后:);7for(Objecta:list)8System.out.print(a+t);9list.remove(赵七赵七);list.remove(1);10inti;11System.out.println(n删除元素之后:删除元素之后:);12for(i=0;ilist.size();i+)13

223、14Objecto=list.get(i);/取得元素取得元素15System.out.print(o+t);161718常用泛型类-LinkedList类数据结构中的链表具有如下特点:(1)分配内存空间不是必须是连续的;(2)插入、删除操作快;(3)查找元素比较慢,必须得从第一个元素开始遍历查询、直到查找到或链表末端。在Java语言中,LinkedList类可以实现了链接列表功能的类。当然,还可以利用LinkedList类队列和栈的功能操作。常用泛型类-LinkedList类LinkedList类提供了如下方法:LinkedList()构造一个空列表。构造一个空列表。LinkedList(C

224、ollectionc)构造一个包含指定集合中的元素的列构造一个包含指定集合中的元素的列表,这些元素按其集合的迭代器返回的顺序排列。表,这些元素按其集合的迭代器返回的顺序排列。boolean add(Eo)将指定元素追加到此列表的结尾。将指定元素追加到此列表的结尾。voidadd(intindex,Eelement)在此列表中指定的位置插入指定的元素。在此列表中指定的位置插入指定的元素。boolean addAll(Collectionc)追加指定追加指定collection中的所有元中的所有元素到此列表的结尾,顺序是指定素到此列表的结尾,顺序是指定collection的迭代器返回这些元素的顺序

225、。的迭代器返回这些元素的顺序。boolean addAll(intindex,Collectionc)将指定集合中的所有元将指定集合中的所有元素从指定位置开始插入此列表。素从指定位置开始插入此列表。voidaddFirst(Eo)将给定元素插入此列表的开头。将给定元素插入此列表的开头。voidaddLast(Eo)将给定元素追加到此列表的结尾。将给定元素追加到此列表的结尾。voidclear()从此列表中移除所有元素。从此列表中移除所有元素。常用泛型类-LinkedList类Eget(intindex)返回此列表中指定位置处的元素。返回此列表中指定位置处的元素。EgetFirst()返回此列表

226、的第一个元素。返回此列表的第一个元素。EgetLast()返回此列表的最后一个元素。返回此列表的最后一个元素。intindexOf(Objecto)返回此列表中首次出现的指定元素的索引,如果列表返回此列表中首次出现的指定元素的索引,如果列表中不包含此元素,则返回中不包含此元素,则返回-1。intlastIndexOf(Objecto)返回此列表中最后出现的指定元素的索引,如果返回此列表中最后出现的指定元素的索引,如果列表中不包含此元素,则返回列表中不包含此元素,则返回-1。ListIteratorlistIterator(intindex)返回此列表中的元素的列表迭代器(按适返回此列表中的元素

227、的列表迭代器(按适当顺序),从列表中指定位置开始。当顺序),从列表中指定位置开始。booleanoffer(Eo)将指定元素添加到此列表的末尾(最后一个元素)。将指定元素添加到此列表的末尾(最后一个元素)。Epeek()找到但不移除此列表的头(第一个元素)。找到但不移除此列表的头(第一个元素)。Epoll()找到并移除此列表的头(第一个元素)。找到并移除此列表的头(第一个元素)。Eremove()找到并移除此列表的头(第一个元素)。找到并移除此列表的头(第一个元素)。Eremove(intindex)移除此列表中指定位置处的元素。移除此列表中指定位置处的元素。booleanremove(Obj

228、ecto)移除此列表中首次出现的指定元素。移除此列表中首次出现的指定元素。EremoveFirst()移除并返回此列表的第一个元素。移除并返回此列表的第一个元素。EremoveLast()移除并返回此列表的最后一个元素。移除并返回此列表的最后一个元素。Eset(intindex,Eelement)将此列表中指定位置的元素替换为指定的元素。将此列表中指定位置的元素替换为指定的元素。intsize()返回此列表的元素数。返回此列表的元素数。常用泛型类-LinkedList类举例例9-10定义链表,链表中的数据是学生成绩的对象。如下图所示。(1)先定义一学生节点类先定义一学生节点类StudentNo

229、de,其代码如下:,其代码如下:1publicclassStudentNode2privateStringname;3privateintscore;45(2)其次,再定义一测试类其次,再定义一测试类LinkedListTest。常用泛型类-LinkedList类举例2/输入一个合法的分数,该分数在区间输入一个合法的分数,该分数在区间0,100。3publicstaticintinputScore(Scannersc)4intscore;5System.out.print(输入学生成绩应该在输入学生成绩应该在0,100区间内区间内:);6score=sc.nextInt();7while(sc

230、ore100)8System.out.print(输入学生成绩应该在输入学生成绩应该在0,100区间内区间内:);9score=sc.nextInt();1011returnscore;1214publicstaticvoidprintLinkedList(LinkedListlist)15Iteratorit=list.iterator();16intc=0;17while(it.hasNext()18if(c!=0)19System.out.print(-);20EstudentNode=it.next();21System.out.print(studentNode);22c+;2324

231、System.out.println();2526publicstaticvoidmain(Stringargs)27/创建空链表创建空链表28LinkedListlist=newLinkedList();29Scannersc=newScanner(System.in,gbk);/可以输入汉字可以输入汉字30Stringname;31intscore;32System.out.print(输入姓名输入姓名(输入输入q退出退出):);33name=sc.next();34while(pareTo(q)!=0)35score=inputScore(sc);36Estu=newE(name,sco

232、re);37list.add(stu);/将学生节点加到链表表尾将学生节点加到链表表尾38System.out.print(输入姓名输入姓名(输入输入q退出退出):);39name=sc.next();4041System.out.println(链表数据如下:链表数据如下:);42printLinkedList(list);4344常用泛型类-Stack类栈栈又叫堆栈,它是一种操作受限制的线性表,它只仅允许在的栈顶进行插入和删除运算。相对地,而另一端称之为栈底,如图所示。向一个栈中插入元素称之为进栈(或叫作入栈或压栈),它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又

233、称作出栈(或退栈)。常用泛型类-Stack类在java语言中,Stack类表示后进先出的对象堆栈,其父类是Vector类。Stack类中的主要方法如下:boolean empty()测试堆栈是否为空。测试堆栈是否为空。Epeek()查看栈顶对象而不移除它。查看栈顶对象而不移除它。Epop()移除栈顶对象并作为此函数的值返回该对象。移除栈顶对象并作为此函数的值返回该对象。Epush(Eitem)把项压入栈顶。把项压入栈顶。intsearch(Objecto)返回对象在栈中的位置,以返回对象在栈中的位置,以1为基数。为基数。常用泛型类-Stack类举例例9-11输入一个十进制数,将其转换成n进制数

234、。(StackTest.java)10025025212262321000100112100812818044110016604616常用泛型类-Stack类举例29while(!(n=2|n=8|n=16)30System.out.println(输入需要转换的进制输入需要转换的进制(2,8,16):);31n=sc.nextInt();3233intr=0,s;34s=number;35while(s!=0)36r=s%n;37stack.push(r);/余数进栈余数进栈38s=s/n;3940System.out.print(number+转换成转换成+n+进制数,结果是进制数,结果是

235、:);41while(!stack.empty()42intt=(int)stack.pop();/注意需要强制转化出栈的元素注意需要强制转化出栈的元素43print(t,n);4445System.out.println();/换行换行46472publicstaticvoidprint(intr,intn)3if(r=n)4System.out.println(error);5else67switch(n)8case2:9case8:10System.out.print(r);11break;12case16:13charch;14if(r=10)15ch=(char)(A+r-10);1

236、6System.out.print(ch);1718else19System.out.print(r);202122常用泛型类-HashSet类HashSet类是基于Set接口的实现类,它具有如下特点:(1)不能保证元素的排列顺序,顺序有可能发生变化;(2)集合中的元素可以是null,但只能放入一个null;(3)HashSet集合判断两个元素相等的依据是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值相同。常用泛型类-HashSet类HashSet类的主要方法如下:HashSet()构造一个新的空集合。构造一个新的空集合。HashSet(Collection

237、c)构造一个包含指定构造一个包含指定collection中的元素的中的元素的新新set。HashSet(intinitialCapacity)构造一个新的空集合。构造一个新的空集合。booleanadd(Eo)如果此集合中还不包含指定元素,则添加指定元素。如果此集合中还不包含指定元素,则添加指定元素。voidclear()从此集合中移除所有元素。从此集合中移除所有元素。Objectclone()返回此返回此HashSet实例的浅表复制:并没有克隆这些元素本实例的浅表复制:并没有克隆这些元素本身。身。booleancontains(Objecto)如果此集合包含指定元素,则返回如果此集合包含指定

238、元素,则返回true,否则返,否则返回回false。booleanisEmpty()如果此集合不包含任何元素,则返回如果此集合不包含任何元素,则返回true。Iteratoriterator()返回对此集合中元素进行迭代的迭代器。返回对此集合中元素进行迭代的迭代器。booleanremove(Objecto)如果指定元素存在于此集合中,则将其移除。如果指定元素存在于此集合中,则将其移除。intsize()返回此集合中的元素的数量(集合的容量)。返回此集合中的元素的数量(集合的容量)。常用泛型类-HashSet类举例例9-12创建集合A和集合B,求、。16/得到集合得到集合a和集合和集合b的交集

239、的交集ab17publicstaticHashSetinterSection(HashSeta,HashSetb)18HashSetc=newHashSet();19Iteratorit=a.iterator();20while(it.hasNext()21intt=(int)it.next();22if(b.contains(t)/如果集合如果集合b中包含中包含t时时23c.add(t);2425returnc;2627/得到集合得到集合a和集合和集合b的并集的并集ab28publicstaticHashSetunionSection(HashSeta,HashSetb)29HashSetc

240、=newHashSet(a);30c.addAll(b);/将集合将集合b加入到加入到c31returnc;3233/随机产生n个元素的集合,集合元素在区间0,num),34publicstaticHashSetgetSet(intnum,intn)35HashSeth=newHashSet();36Randomrandom=newRandom();37intnumber;38intc=0;39while(cn)40/随机产生在区间(0,num)的数41number=random.nextInt(num);42h.add(number);/将number加入到集合中43c+;4445retur

241、nh;46常用泛型类-TreeSet类5.TreeSet类TreeSet类亦是基于Set接口的实现类,而且TreeSet是Set的子接口SortedSet的实现类。TreeSet类可以确保它的集合元素处于排序状态。TreeSet支持两种排序方式(自然排序和定制排序),其中自然排序是默认的排序方式。向TreeSet中加入的应该是同一个类的对象。TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0。常用泛型类-TreeSet类TreeSet类中的主要方法如下:TreeSet()构造一个新的空集合,该集合按照元素的自然顺序排

242、序。TreeSet(Collectionc)构造一个新集合,包含指定collection中的元素,这个新set按照元素的自然顺序排序。TreeSet(Comparatorc)构造一个新的空集合,该集合根据指定的比较器进行排序。TreeSet(SortedSets)构造一个新集合,该集合所包含的元素与指定的已排序集合包含的元素相同,并按照相同的顺序对元素进行排序。booleanadd(Eo)将指定的元素添加到集合(如果尚未存在于该集合中)。booleanaddAll(Collectionc)将指定collection中的所有元素添加到此集合中。voidclear()移除集合中的所有元素。Comp

243、aratorcomparator()返回用于确定已排序集合顺序的比较器,或者,如果此树集合使用其元素的自然顺序,则返回null。常用泛型类-TreeSet类booleancontains(Objecto)如果集合包含指定的元素,则返回true。Efirst()返回已排序集合中的第一个(最小)元素。SortedSetheadSet(EtoElement)返回此集合的部分视图,要求其元素严格小于toElement。booleanisEmpty()如果集合是空,则返回true,否则返回false。Iteratoriterator()返回对此集合中的元素进行迭代的迭代器。Elast()返回已排序集合中

244、当前的最后一个(最大)元素。booleanremove(Objecto)将指定的元素从集合中移除(如果该元素存在于此集合中)。intsize()返回集合中的元素个数(其容量)。SortedSetsubSet(EfromElement,EtoElement)返回此集合的部分视图,其元素从fromElement(包括)到toElement(不包括)。SortedSettailSet(EfromElement)返回集合的部分视图,其元素大于或等于fromElement。常用泛型类-TreeSet类举例例例9-13 创建集合建集合A和集合和集合B,计算笛卡算笛卡尔积 ,说明:说明:。(1)定义自定义类

245、定义自定义类ENode类,注意:类,注意:ENode类必须实现类必须实现java.lang.Comparable接口,所以在接口,所以在ENode类中必须实现抽象类中必须实现抽象方法方法compareTo(To)。常用泛型类-TreeSet类举例1publicclassENodeimplementsComparable2intx,y;.26publicintcompareTo(Objecto)27ENodeobject1=(ENode)this;28ENodeobject2=(ENode)o;29if(object1.getX()object2.getX()30return1;3132else

246、/=33if(object1.getX()object2.getY()38return1;39else40if(object1.getY()object2.getY()41return-1;42else43return0;444546常用泛型类-TreeSet类举例(2)定义测试类TreeSetTest中的方法:30/随机产生随机产生n个元素的集合个元素的集合,集合元素在区间集合元素在区间0,num),31publicstaticTreeSetgetSet(intnum,intn)32TreeSeth=newTreeSet();33Randomrandom=newRandom();34intn

247、umber;35while(h.size()n)36/随机产生在区间随机产生在区间(0,100)的数的数37number=random.nextInt(num);38h.add(number);/将将number加入到集合中加入到集合中3940returnh;4142/得到集合a和集合b笛卡尔积43publicstaticTreeSetgetDecare(TreeSeta,TreeSetb)44/集合元素是ENode类型的元素45TreeSettts=newTreeSet();46Iteratorita=a.iterator();47while(ita.hasNext()48inttemp=(

248、int)ita.next();49Iteratoritb=b.iterator();50while(itb.hasNext()51inttb=(int)itb.next();52ENodeelement=newENode(temp,tb);53tts.add(element);545556returntts;57常用泛型类-HashMapHashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。(1)HashMap是用链地址法进行处理,多个是用链地址法进行处理,多个key对应于表中的一个索引位置的时对应于表中的一个索引位置的时候进行链地址处理,候进行链地址处理,HashMap其实

249、就是一个数组其实就是一个数组+链表的形式。链表的形式。(2)当有多个当有多个key的值相同时,的值相同时,HashMap中只保存具有相同中只保存具有相同key的一个节点,也的一个节点,也就是说相同就是说相同key的节点会进行覆盖。的节点会进行覆盖。(3)在在hashmap中查找一个值,需要两次定位,先找到元素在数组的位置的链中查找一个值,需要两次定位,先找到元素在数组的位置的链表上,然后在链表上查找,在表上,然后在链表上查找,在HashMap中的第一次定位是由中的第一次定位是由hash值确定的,值确定的,第二次定位由第二次定位由key和和hash值确定。值确定。(4)节点在找到所在的链后,插入

250、链中是采用的是头插法,也就是新节点都插节点在找到所在的链后,插入链中是采用的是头插法,也就是新节点都插在链表的头部。在链表的头部。(5)在在Hashmap类定义了一内部类类定义了一内部类Entry,相当于图,相当于图9-8中的数据项,该类包括中的数据项,该类包括next、key、value、hash四个四个属性,如图所示。属性,如图所示。常用泛型类-HashMapHashMap类的主要方法如下:类的主要方法如下:HashMap()构造一个具有默认初始容量构造一个具有默认初始容量(16)和默认加载和默认加载因子因子(0.75)的空的空HashMap。HashMap(intinitialCapac

251、ity)构造一个带指定初始容量和构造一个带指定初始容量和默认加载因子默认加载因子(0.75)的空的空HashMap。HashMap(intinitialCapacity,floatloadFactor)构造一个带构造一个带指定初始容量和加载因子的空指定初始容量和加载因子的空HashMap。HashMap(Mapm)构造一个映构造一个映射关系与指定射关系与指定Map相同的相同的HashMap。voidclear()从此映射中移除所有映射关系。从此映射中移除所有映射关系。booleancontainsKey(Objectkey)如果此映射包含对于指如果此映射包含对于指定的键的映射关系,则返回定的键

252、的映射关系,则返回true。常用泛型类-HashMapbooleancontainsValue(Objectvalue)如果此映射将一个或多个键映射到指定值,则返回true。SetMap.EntryentrySet()返回此映射所包含的映射关系的collection视图。Vget(Objectkey)返回指定键在此标识哈希映射中所映射的值,如果对于此键来说,映射不包含任何映射关系,则返回null。booleanisEmpty()如果此映射不包含键-值映射关系,则返回true。SetkeySet()返回此映射中所包含的键的set视图。Vput(Kkey,Vvalue)在此映射中关联指定值与指定键

253、。Vremove(Objectkey)如果此映射中存在该键的映射关系,则将其删除。intsize()返回此映射中的键-值映射关系数。Collectionvalues()返回此映射所包含的值的collection视图。常用泛型类-HashMap举例例9-14人们要选出自己心中最厉害的军事家,其中候选人有司马懿、诸葛亮、陆逊、曹操、周瑜,而选民有若干人(人数不定)。投票完成后,统计各候选人得票情况。(1)定义定义候选人投票信息候选人投票信息Vote类,其代码如下:类,其代码如下:1publicclassVote2privateStringvoterNames;/投票人列表投票人列表3private

254、intcount;/得票得票数量数量412publicStringgetVoterNames()13returnvoterNames;1419/得票数量自动增加得票数量自动增加1,并设置投票人列表,并设置投票人列表20publicvoidincrease(StringvoterName)21this.voterNames=this.voterNames+,+voterName;22this.count+;2324常用泛型类-HashMap举例(2)定义测试类HashMapTest。(HashMapTest.java)返回目录9.3反射Java虚拟机加载类过程。反射反射就是把普通Java类中的各

255、种成分映射成对应的Java类。如一般的Java类包括由方法、构造方法、属性字段以及修身符等信息;而在Java语言中,Method、Constructor、Field以及Modifier等和这些成分一一对应。JVM虚拟机反射过程(以反射Triangle类为例)。反射在Java语言中,有关反射的大部分类和接口定义在软件包java.lang.reflect中。返回目录9.3.2与反射相关的类1.Class类Java程序在运行过程中,Java运行时系统一直对全部的Java对象进行运行时类型标识RTTI(即Run-TimeTypeIdentification的简称)。该信息记录了每个对象所属的类。Jav

256、a虚拟机根据运行时类型信息自动选择正确的方法运行。而Class类正是用来保存这些类型信息的类。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。与反射相关的类-Class类Class类中给的主要方法如下:Tcast(Objectobj)将一个对象强制转换成此Class对象所表示的类或接口。staticClassforName(StringclassName)返回与带有给定字符串名的类或接口相关联的Class对象。ClassgetClasses()返回一个包含某些Class对象的数组,这些对象表示属于此Class对象所表示的类的成员的所有公共类和接口,包括从超

257、类和公共类继承的以及通过该类声明的公共类和接口成员。ClassgetDeclaredClasses()返回Class对象的一个数组,这些对象反映声明为此Class对象所表示的类的成员的所有类和接口,包括该类所声明的公共、保护、默认(包)访问及私有类和接口,但不包括继承的类和接口。FieldgetField(Stringname)返回一个Field对象,它反映此Class对象所表示的类或接口的指定公共成员字段。FieldgetFields()返回一个包含某些Field对象的数组,这些对象反映此Class对象所表示的类或接口的所有可访问公共字段。Type getGenericInterfaces(

258、)返回表示某些接口的返回表示某些接口的Type,这些接口由此对,这些接口由此对象所表示的类或接口直接实现。象所表示的类或接口直接实现。TypegetGenericSuperclass()返回表示此返回表示此Class所表示的实体(类、接口、所表示的实体(类、接口、基本类型或基本类型或void)的直接超类的)的直接超类的Type。Class getInterfaces()确定此对象所表示的类或接口实现的接口。确定此对象所表示的类或接口实现的接口。ConstructorgetConstructors()返回一个包含某些返回一个包含某些Constructor对象的数对象的数组,这些对象反映此组,这些

259、对象反映此Class对象所表示的类的所有公共构造方法。对象所表示的类的所有公共构造方法。ConstructorgetDeclaredConstructors()返回返回Constructor对象的一个数组,对象的一个数组,这些对象反映此这些对象反映此Class对象表示的类声明的所有构造方法对象表示的类声明的所有构造方法。MethodgetMethods()返回一个包含某些返回一个包含某些Method对象的数组,这些对象的数组,这些对象反映此对象反映此Class对象所表示的类或接口(包括那些由该类或接口声明的以对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口

260、)的公共及从超类和超接口继承的那些的类或接口)的公共member方法。方法。MethodgetDeclaredMethods()返回返回Method对象的一个数组,这些对象反对象的一个数组,这些对象反映此映此Class对象表示的类或接口声明的所有方法,包括公共、保护、默认对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。(包)访问和私有方法,但不包括继承的方法。StringgetName()以以String的形式返回此的形式返回此Class对象所表示的实体(类、接对象所表示的实体(类、接口、数组类、基本类型或口、数组类、基本类型或void)名称。)

261、名称。PackagegetPackage()获取此类的包。Tcast(Objectobj)将一个对象强制转换成此Class对象所表示的类或接口。staticClassforName(StringclassName)返回与带有给定字符串名的类或接口相关联的Class对象。intgetModifiers()返回此类或接口以整数编码的Java语言修饰符。StringgetName()以String的形式返回此Class对象所表示的实体(类、接口、数组类、基本类型或void)名称。PackagegetPackage()获取此类的包。Class getSuperclass()返回表示此Class所表示的

262、实体(类、接口、基本类型或void)的超类的Class。TnewInstance()创建此Class对象所表示的类的一个新实例。与反射相关的类-Class类举例例9-1Reflect类(Reflect.java)创建了如下静态方法outputMsgOfClass()、outputFields(Classc)、outputConstructors(Classc)、outputMethods(Classc)、outputAllInformationOfClass(Classc)。与反射相关的类-Class类举例(1)静态方法outputMsgOfClass(Classc)定义如下:1/输出类或接口

263、定义的部分信息2publicstaticvoidoutputMsgOfClass(Classc)3Stringmsg=;4intmodifiers=c.getModifiers();/得到修饰符编码值5msg=getModifierStr(modifiers);/得到类修饰符字符串6if(c.isInterface()7msg=msg+interface;8else9if(c.isEnum()10msg=msg+enum;11else12msg=msg+class;13msg=msg+c.getName();14System.out.print(msg);15/得到父类16Classparen

264、t=c.getSuperclass();/得到父类17Objectob=newObject();18Classobc=ob.getClass();19/如果父类不是Object时,就输出extends父类名20if(parent!=null&parent.getName().compareTo(obc.getName()!=0)21System.out.print(extends+parent.getCanonicalName();2223Classinterfaces=c.getInterfaces();/得到接口数组24for(inti=0;iinterfaces.length;i+)25

265、26if(i=0)/输出第一个接口2728System.out.print(implements);29System.out.print(interfacesi.getName();3031else/输出非第一个接口32System.out.print(,+interfacesi.getName();3334System.out.println();35与反射相关的类-Class类举例(2)静态方法静态方法outputFields(Classc)定义如下:定义如下:1/输出类中的所有属性输出类中的所有属性2publicstaticvoidoutputFields(Classc)3Fieldfs

266、;4inti;5fs=c.getDeclaredFields();/得到类中所有的成员属性,保存到数组中得到类中所有的成员属性,保存到数组中6/输出所有的属性输出所有的属性7for(i=0;ifs.length;i+)8outputField(fsi);/输出单个方法输出单个方法92publicstaticvoidoutputConstructors(Classc)3Constructorconstructors;4/得类中所有公共构造方法的数组5constructors=c.getDeclaredConstructors();6for(Constructorconstructor:const

267、ructors)7outputConstructor(constructor);/输出一个构造方法89与反射相关的类-Class类举例2publicstaticvoidoutputMethods(Classc)3Methodms;4inti;5ms=c.getDeclaredMethods();/得到类中声明的所有方法得到类中声明的所有方法6for(i=0;ims.length;i+)7outputMethod(msi);/输出单个方法输出单个方法8与反射相关的类-Class类举例1/输出类对象的所有信息,包括超类的所有信息2publicstaticvoidoutputAllInformati

268、onOfClass(Classc)throwsException3/得到c对象的父类4Classparent=c.getSuperclass();5Objectob=newObject();6Classobc=ob.getClass();7/如果父类不是Object,则输出父类的所有信息。8if(parent!=null&parent.getName().compareTo(obc.getName()!=0)9outputAllInformationOfClass(parent);10Stringmsg;11msg=(c.isInterface()?接口:(c.isEnum()?枚举:类);1

269、2System.out.println(反射+c.getCanonicalName()+msg);13System.out.print(-);14System.out.println(-);15outputMsgOfClass(c);/输出类对象c的部分信息16outputFields(c);/输出对象c的属性成员信息17outputConstructors(c);/输出对象c构造方法18outputMethods(c);/输出对象c的非构造方法19System.out.println();20outputInterfaces(c);/如果类对象c实现了部分接口,则输出这些接口信息。21与反射

270、相关的类-Class类举例2.修饰符类Modifier一般类中的属性、构造方法、一般的方法都应该被public、private、protected、static等修饰符修饰。而Modifier类提供了static方法和常量,对类和成员访问修饰符进行解码。修饰符集被表示为整数,用不同的位位置表示不同的修饰符。为了判断是否被某些修饰符修饰,Modifier提供了如下方法:staticbooleanisXy(intmod)如果整数参数包括xy修饰符,则返回true,否则返回false。其中xy可以是abstract、final、interface、native、private、protected、p

271、ublic、static、strictfp、synchronized、transient、volatile等。而Xy是跟xy一样,只不过其首字母要大写。与反射相关的类-Class类举例例9-2Reflect类(在Reflect.java文件中)定义了得到修饰符串的静态方法getModifierStr(intmode)。2publicstaticStringgetModifierStr(intmod)3Stringmsg=;4if(Modifier.isPublic(mod)/被public修饰5msg=msg+public;6if(Modifier.isPrivate(mod)/被privat

272、e修饰7msg=msg+private;8if(Modifier.isProtected(mod)/被protected修饰9msg=msg+protected;10if(Modifier.isStatic(mod)/被static修饰11msg=msg+static;12if(Modifier.isSynchronized(mod)/被synchronized修饰13msg=msg+synchronized;14if(Modifier.isStrict(mod)/被strict修饰15msg=msg+strict;16if(Modifier.isTransient(mod)/被transie

273、nt修饰17msg=msg+transient;18if(Modifier.isVolatile(mod)/被volatile修饰19msg=msg+volatile;20if(Modifier.isAbstract(mod)/被abstract修饰21msg=msg+abstract;22if(Modifier.isFinal(mod)/被final修饰23msg=msg+final;24returnmsg;25与反射相关的类-Class类举例3.AccessibleObjectAccessibleObject类是Field、Method和Constructor对象的基类。它提供了将反射的对

274、象标记为在使用时取消默认Java语言访问控制检查的能力。对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用Field、Method或Constructor对象来设置或获得字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。与反射相关的类4.FieldField提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。例9-2Reflect类定义了输出一个成员属性的静态方法outputField(Fieldfs)。1/输出一个成员属性2publicstaticvoidoutputField(Fieldfs)3Strin

275、gmsg;4intmodifiers=fs.getModifiers();/得到属性的修饰符编码值5msg=getModifierStr(modifiers);/得到属性的修饰符字符串6System.out.print(msg+);7Typetp=fs.getType();/得到属性的数据类型8System.out.println(tp+fs.getName()+;);/得到属性的名称9与反射相关的类5.Constructor类Constructor提供关于类的单个构造方法的信息以及对类的访问权限。Constructor允许在将实参与带有基础构造方法的形参的newInstance()匹配时进行

276、扩展转换。例9-3Reflect类(在Reflect.java文件中)定义了输出一个构造方法的静态方法outputConstructor(Constructorconstructor)。与反射相关的类1/输出一个构造方法输出一个构造方法2publicstaticvoidoutputConstructor(Constructorconstructor)3Stringmsg;4intmodifiers=constructor.getModifiers();/得到修饰符编码值得到修饰符编码值5msg=getModifierStr(modifiers);/得到修饰符字符串得到修饰符字符串6System

277、.out.print(msg+);/输出修饰符输出修饰符7System.out.print(constructor.getName()+();/输出构造方法名称输出构造方法名称8Typetps=constructor.getParameterTypes();/得到构造方法参数列表得到构造方法参数列表9inti;10/输出所有参数输出所有参数11for(i=0;itps.length;i+)12if(i=0)13System.out.print(tpsi+(char)(a+i);/输出参数输出参数14else15System.out.print(,+tpsi+(char)(a+i);/输出参数输

278、出参数161718System.out.println(););19与反射相关的类6.MethodMethod类提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。例9-4Reflect类(在Reflect.java文件中)定义了输出一个方法的静态方法。与反射相关的类2publicstaticvoidoutputMethod(Methodms)3Stringmsg;4intmodifiers=ms.getModifiers();/得到方法的修饰符编码值得到方法的修饰符编码值5msg=getModifierStr(modifiers);/得到方法的修饰符串得到方法的修饰符串6System

279、.out.print(msg+);7/ms.getReturnType()方法得到返回值类型方法得到返回值类型8System.out.print(ms.getReturnType().getCanonicalName()+);9System.out.print(ms.getName()+();/得到方法名称得到方法名称10/得到方法类的参数类型,保存到数组中得到方法类的参数类型,保存到数组中11Typetps=ms.getGenericParameterTypes();12inti;13for(i=0;itps.length;i+)14if(i=0)15System.out.print(tps

280、i+(char)(a+i);/输出参数输出参数16else17System.out.print(,+tpsi+(char)(a+i);/输出参数输出参数1819System.out.println(););20与反射相关的类7.Reflect类的类的main()定义如下:定义如下:1publicstaticvoidmain(Stringargs)throwsException2Classc=null;3c=Class.forName(Triangle);4outputAllInformationOfClass(c);5Trianglet=null;6c=Class.forName(Triang

281、le);7/创建创建Triangle类的默认实例类的默认实例8System.out.println(创建创建Triangle类的默认实例类的默认实例);9t=(Triangle)c.newInstance();10t.setA(3);11t.setB(4);12t.setC(5);13t.adjustName();14t.printFigure();15本章结束!第10章Java异常处理本章内容10.1Java异常层次结构10.2Java异常处理语法10.3抛出异常10.1Java异常层次结构10.2Java异常处理语法Java异常处理的完整语法是:Java异常处理语法需要注意的问题是:(1)

282、try、catch、finally三个语句块都不能独自使用,三者可以组成如下三种结构.trycatch(异常类型名异常类型名e)finallytrycatch(异常类型名异常类型名e)tryfinally10.3抛出异常抛出异常主要有通过throw和throws语句。在方法体内,用throw来抛出一个异常,throw抛出异常语法格式为:throw异常对象名字;throws表示用来声明方法可能会抛出异常类别,用在方法名后,语法格式为:修饰符方法名(参数列表)throws异常类型1,异常类型2.异常类型n。异常举例例10-1下面给出一个异常的简单例子,三角形类Triangle10_1,异常类Tri

283、angleException1、异常类TriangleException2。(1)定义异常类定义异常类TriangleException1,该异常类指出存在小于或等,该异常类指出存在小于或等于于0的边长情况。的边长情况。1classTriangleException1extendsException2privateStringmsg;3TriangleException1()4msg=存在小于或等于存在小于或等于0的边长。的边长。;56Override7publicStringtoString()8return异常异常:+msg;910异常举例(2)定义异常类定义异常类TriangleExce

284、ption2,该异常类报告三角形的任意,该异常类报告三角形的任意两条边边长之和小于或等于第三条边长错误。两条边边长之和小于或等于第三条边长错误。1classTriangleException2extendsException2Stringmsg;3TriangleException2()4msg=异常:三角形的任意两条边边长之和小于或等于第三条边长。;56publicStringtoString()7returnmsg;89异常举例1publicclassTriangle10_12privatedoublea,b,c;3Triangle10_1(doublea,doubleb,doublec)

285、4this.a=a;5this.b=b;6this.c=c;78/*注意下面语句,该方法可能会抛出异常类注意下面语句,该方法可能会抛出异常类TriangleException1,TriangleException29的异常。的异常。*/10publicdoublegetArea()throwsTriangleException1,TriangleException211TriangleException1t1=newTriangleException1();12TriangleException2t2=newTriangleException2();13if(a=0|b=0|c=0)14thr

286、owt1;/抛出异常抛出异常15if(a+b=c|b+c=a|a+c=b)16throwt2;/抛出异常抛出异常17doublep,s;18p=(a+b+c)/2.0;19s=Math.sqrt(p*(p-a)*(p-b)*(p-c);20returns;21异常举例22publicstaticvoidmain(Stringargs)23Scanners=newScanner(System.in);24doublea,b,c;25System.out.print(输入三角形的输入三角形的3条边长条边长:);26a=s.nextDouble();27b=s.nextDouble();28c=s.

287、nextDouble();29try30Triangle10_1t1=newTriangle10_1(a,b,c);31System.out.println(三角形的面积是:三角形的面积是:+t1.getArea();32catch(TriangleException1e1)/可能发生异常可能发生异常e133System.out.println(e1);3435catch(TriangleException2e2)/可能发生异常可能发生异常e136System.out.println(e2);3738finally39/该语句无论上面异常是否发生,都会执行。该语句无论上面异常是否发生,都会执行

288、。40System.out.println(求三角形面积!求三角形面积!);414243本章结束!第11章Java的图形界面设计基础本章内容11.1AWT11.2容器概念11.3窗格概念11.4布局管理器概念11.5Java事件处理11.1AWT在Java图形库中,目前最著名的三大GUI库分别是:(1)抽象窗口工具集AWT(AbstractWindowToolkit),包含于所有的JavaSDK中。(2)高级图形库Swing,亦包含于Java开发包中Java开发工具集。(3)标准窗口部件库SWT(StandardWidgetToolkit),在Eclipse中可以利用。AWTjava.awt包

289、中提供了GUI设计所使用的类和接口,在下图中,可以看到主要GUI类之间的继承关系。组件组件是一个以图形化的方式显示在屏幕上并能与用户进行交互的对象,例如一个按钮、一个标签等。类java.awt.Component是许多组件类的父类,Component类中封装了组件通用的方法和属性。Component类的主要成员方法包括:publicvoidsetBackground(Colorbc)设置背景色publicvoidsetForeground(Colorfc)设置前景色publicColorgetBackground(Colorgbc)获取背景色publicColorgetForeGround(C

290、olorgfc)获取前景色与颜色有关的方法与颜色有关的方法publicvoidsetFont(Fontfont)设置字体publicFontgetFont(Fontfont)获取字体FontMetricsgetFontMetrics(Fontfont)获得指定字体的字体规格。与字体有关的主要方法与字体有关的主要方法组件publicvoidsetSize(intw,inth)设置组件大小(包括宽度和高度)publicvoidsetLocation(intx,inty)设置组件在容器中的位置publicDimensiongetSize()返回组件的大小(组件的宽度和高度)publicPointge

291、tLocation(intx,inty)返回组件在容器中的位置(左上角坐标)publicvoidsetBounds(intx,inty,intwidth,intheight)设置组件在容器中的位置及组件大小publicRectanglegetBounds()返回组件在容器中的位置和大小voidsetVisible(booleanb)根据参数b的值显示或隐藏此组件。voidsetEnabled(booleanb)根据参数b的值启用或禁用此组件。ContainergetParent()获得此组件的父级。voidvalidate()确保组件具有有效的布局。voidinvalidate()使此组件无效

292、。voiddoLayout()提示布局管理器布局此组件。voidrequestFocus()请求此Component获得输入焦点,并且此Component的顶层祖先成为获得焦点的Window。组件的主要方法(续)voidsetVisible(booleanb)根据参数b的值显示或隐藏此组件。voidsetEnabled(booleanb)根据参数b的值启用或禁用此组件。ContainergetParent()获得此组件的父级。voidvalidate()确保组件具有有效的布局。voidinvalidate()使此组件无效。voiddoLayout()提示布局管理器布局此组件。voidreque

293、stFocus()请求此Component获得输入焦点,并且此Component的顶层祖先成为获得焦点的Window。voidpaint(Graphicsg)绘制此组件。voidpaintAll(Graphicsg)绘制此组件及其所有子组件。voidrepaint()重绘此组件。voidrepaint(intx,inty,intwidth,intheight)重绘组件的指定矩形区域。voidrepaint(longtm)重绘组件。voidrepaint(longtm,intx,inty,intwidth,intheight)在tm毫秒内重绘组件的指定矩形区域。voidupdate(Graphi

294、csg)更新组件。组件的主要方法(续)GraphicsgetGraphics()为组件创建一个图形上下文。GraphicsConfigurationgetGraphicsConfiguration()获得与此Component相关的GraphicsConfiguration。intgetHeight()返回组件的当前高度。返回组件的当前高度。intgetWidth()返回组件的当前宽度。返回组件的当前宽度。intgetX()返回组件原点的当前返回组件原点的当前x坐标。坐标。intgetY()返回组件原点的当前返回组件原点的当前y坐标。坐标。PointgetLocation()获得组件的位置,形

295、式是指定组件左上角的一个点。获得组件的位置,形式是指定组件左上角的一个点。PointgetLocation(Pointrv)将组件的将组件的x,y原点存储到原点存储到“返回值返回值”rv中并返回中并返回rv。PointgetLocationOnScreen()获得组件的位置,形式是一个指定屏幕坐标空间中组件左上角的一个点。获得组件的位置,形式是一个指定屏幕坐标空间中组件左上角的一个点。Component getComponentAt(intx,inty)确定此组件或其直接子组件之一是否包含(确定此组件或其直接子组件之一是否包含(x,y)位置,并且如果是,)位置,并且如果是,则返回包含该位置的组

296、件。则返回包含该位置的组件。Component getComponentAt(Pointp)返回包含指定点的组件或子组件。返回包含指定点的组件或子组件。booleancontains(intx,inty)检查组件是否检查组件是否“包含包含”指定的点,其中指定的点,其中x和和y是相对于此组件的坐标系统定义的。是相对于此组件的坐标系统定义的。booleancontains(Pointp)检查组件是否检查组件是否“包含包含”指定的点,其中该点的指定的点,其中该点的x和和y坐标是相对于此组件的坐标系统坐标是相对于此组件的坐标系统定义的。定义的。RectanglegetBounds()以以Rectang

297、le对象的形式获得组件的边界。对象的形式获得组件的边界。RectanglegetBounds(Rectanglerv)将组件的边界存储到将组件的边界存储到“返回值返回值”rv中并返回中并返回rv。voidsetBounds(intx,inty,intwidth,intheight)移动组件并调整其大小。移动组件并调整其大小。voidsetBounds(Rectangler)移动组件并调整其大小,使其符合新的有界矩形移动组件并调整其大小,使其符合新的有界矩形r。voidsetLocation(intx,inty)将组件移到新位置。将组件移到新位置。voidsetLocation(Pointp)将

298、组件移到新位置。将组件移到新位置。Dimension getSize()以以Dimension对象的形式返回组件的大小。对象的形式返回组件的大小。voidsetSize(Dimensiond)调整组件的大小,使其宽度为调整组件的大小,使其宽度为d.width,高度为,高度为d.height。voidsetSize(intwidth,intheight)调整组件的大小,使其宽度为调整组件的大小,使其宽度为width,高度为,高度为height。了解SwingAWT组件和Swing组件最大的不同是:Swing组件不含本地代码,可以不受硬件平台限制。而AWT组件含有本地代码,跟硬件平台密切相关。由于

299、AWT功能非常有限,在建立图形用户界面时,我们一般都不会用它,而是利用Java中功能更强大的Swing。Swing属于Java基础类库JFC(JavaFoundationClasses)的一部分,它主要帮助我们建立用户界面。了解SwingSwing中的主要类的继承关系GaphicsEnvironment类GaphicsEnvironment类是抽象类,描述了Java应用程序在特定平台上可用的GraphicsDevice对象和Font对象的集合。此GraphicsEnvironment中的资源可以是本地资源,也可以位于远程机器上。GaphicsEnvironment类的主要方法如下:abstra

300、ctGraphics2DcreateGraphics(BufferedImageimg)返回一个呈现指定BufferedImage的Graphics2D对象。abstractFontgetAllFonts()返回一个数组,它包含此GraphicsEnvironment中所有可用字体的像素级实例。abstractStringgetAvailableFontFamilyNames()返回一个包含此GraphicsEnvironment中所有字体系列名称的数组。abstractStringgetAvailableFontFamilyNames(Localel)返回一个包含此GraphicsEnvir

301、onment中所有字体系列名称的数组,它针对默认语言环境进行了本地化。GaphicsEnvironment类abstractGraphics2DcreateGraphics(BufferedImageimg)返回一个呈现指定BufferedImage的Graphics2D对象。abstractFontgetAllFonts()返回一个数组,它包含此GraphicsEnvironment中所有可用字体的像素级实例。abstractStringgetAvailableFontFamilyNames()返回一个包含此GraphicsEnvironment中所有字体系列名称的数组。abstractSt

302、ringgetAvailableFontFamilyNames(Localel)返回一个包含此GraphicsEnvironment中所有字体系列名称的数组,它针对默认语言环境进行了本地化。PointgetCenterPoint()返回Windows应居中的点。abstractGraphicsDevicegetDefaultScreenDevice()返回默认的屏幕GraphicsDevice。staticGraphicsEnvironmentgetLocalGraphicsEnvironment()返回本地GraphicsEnvironment。RectanglegetMaximumWind

303、owBounds()返回居中Windows的最大边界。abstractGraphicsDevicegetScreenDevices()返回所有屏幕GraphicsDevice对象的一个数组。staticbooleanisHeadless()测试此环境是否支持显示器、键盘和鼠标。boolean isHeadlessInstance()返回此图形环境是否支持显示器、键盘和鼠标。voidpreferLocaleFonts()指示在逻辑字体到实际字体的映射关系中特定于语言环境的字体的首选项。颜色类Colorjava.awt包定义了Color类,该类用于封装默认sRGB颜色空间中的颜色,或者用于封装由C

304、olorSpace标识的任意颜色空间中的颜色。每种颜色都有一个隐式的alpha值1.0,或者有一个在构造方法中提供的显式的alpha值。Color类的常用构造方法如下:Color(float r, float g, float b)用指定的红色、绿色和蓝色值创建一种不透明的用指定的红色、绿色和蓝色值创建一种不透明的 sRGB 颜色,这三个颜色值的取值范围在区间颜色,这三个颜色值的取值范围在区间(0.0-,1.0的的)内。内。Color(float r, float g, float b, float alpha)用指定的红色、绿色、蓝色和用指定的红色、绿色、蓝色和alpha值创值创建一种建一种

305、sRGB颜色,颜色,r、g、b和和appha的取值范围在区间的取值范围在区间(0.0-,1.0的的)内。内。Color(int rgb) 用指定的组合用指定的组合RGB值创建一种不透明的值创建一种不透明的sRGB颜色,此颜色,此sRGB值的值的第第16-23位表示红色分量,第位表示红色分量,第8-15位表示绿色分量,第位表示绿色分量,第0-7位表示蓝色分量。位表示蓝色分量。Color(int rgba, boolean hasAlpha) 用指定的组合用指定的组合 RGBA值创建一种值创建一种sRGB 颜色,颜色,此此rgba值的第值的第24-31位表示位表示alpha分量,第分量,第16-2

306、3位表示红色分量,第位表示红色分量,第8-15位表示绿位表示绿色分量,第色分量,第0-7位表示蓝色分量。位表示蓝色分量。hasAlpha表示是否需要表示是否需要alpha分量,分量,hasAlpha值为值为true表示需要表示需要alpha分量,否则不需要分量,否则不需要alpha分量。分量。颜色类ColorColor(int r, int g, int b) 用指定的红色、绿色和蓝色值创建一种不透明的sRGB颜色,r、g和b的取值范围在区间(0,255的)内。Color(int r, int g, int b, int alpha) 用指定的红色、绿色、蓝色和 alpha 值创建一种 sRG

307、B 颜色,r、g、b和appha的取值范围在区间(0,255的)内。Color(int r, int g, int b, int alpha) 用指定的红色、绿色、蓝色和alpha值创建一种sRGB 颜色,r、g、b和appha的取值范围在区间(0,255的)内。例如,Color color1,color2,color3;Color1=new Color(100,100,100);Color2=new Color(0.4,0.5,0.6);Color3=Color.red;Font类Java平台可以区分两种字体平台可以区分两种字体是实际的字体库,包含字形数据和表,这些数据和表使用字体技术(如T

308、rueType或PostScriptType1)将字符序列映射到字形序列。物理字体物理字体逻辑字体逻辑字体逻辑字体不是实际的字体库。而是由Java运行时环境将逻辑字体名称映射到物理字体。映射关系与实现和通常语言环境相关,Font类Font类的主要构造方法有:Font(Stringname,intstyle,intsize)根据指定名称、样式和点大小,创建一个新根据指定名称、样式和点大小,创建一个新Font。booleancanDisplay(charc)检查此检查此Font是否具有指定字符的字形。是否具有指定字符的字形。staticFontcreateFont(intfontFormat,Fi

309、lefontFile)返回一个使用指定字体类型和指定字体文件返回一个使用指定字体类型和指定字体文件的新的新Font。staticFontcreateFont(intfontFormat,InputStreamfontStream)返回一个使用指定字体类型和返回一个使用指定字体类型和输入数据的新输入数据的新Font。staticFontdecode(Stringstr)返回返回str参数所描述的参数所描述的Font。staticFontgetFont(Stringnm)从系统属性列表返回一个从系统属性列表返回一个Font对象。对象。floatgetItalicAngle()返回此返回此Font的

310、斜角。的斜角。intgetNumGlyphs()返回此返回此Font中的字形数量。中的字形数量。StringgetFamily()返回此返回此Font的系列名称。的系列名称。StringgetFontName()返回此返回此Font的字体外观名称。的字体外观名称。StringgetName()返回此返回此Font的逻辑名称。的逻辑名称。StringgetPSName()返回此返回此Font的的postscript名称。名称。intgetSize()返回此返回此Font的点大小,舍入为整数。的点大小,舍入为整数。floatgetSize2D()返回此返回此Font的点大小(以的点大小(以floa

311、t值表示)。值表示)。intgetStyle()返回此返回此Font的样式。的样式。booleanisBold()指示此指示此Font对象的样式是否为对象的样式是否为BOLD。booleanisItalic()指示此指示此Font对象的样式是否为对象的样式是否为ITALIC。booleanisPlain()指示此指示此Font对象的样式是否为对象的样式是否为PLAIN。booleanisTransformed()指示此指示此Font对象是否具有影响其大小以及对象是否具有影响其大小以及Size属性的变换。属性的变换。Font类例11-1列出本地所有字体的名称等信息。1publicclassFon

312、ts2publicstaticvoidprintFont(Fontf)3System.out.print(系列名称系列名称:+f.getFamily()+,名字:名字:);4System.out.println(f.getFontName()+,逻辑名字:逻辑名字:+f.getName();56publicstaticvoidmain(Stringargs)7GraphicsEnvironmentge;8ge=GraphicsEnvironment.getLocalGraphicsEnvironment();9Fontfonts=ge.getAllFonts();10for(Fontfont:

313、fonts)11printFont(font);1213返回目录11.2容器概念容器(Container)是Component的子类,因此容器本身也是一个组件,具有组件的所有性质。但与一般组件,如按钮、标签、文本输入框等不同,容器的主要功能是容纳其他组件。有的容器还可以嵌套其他的容器。而我们称最外层的容器是顶层容器。除顶层容器之外的容器便是中间容器,每个中间容器可以包含若干个基本组件和其他的中间容器。容器概念Container类的主要方法:Componentadd(Componentcomp)将指定组件追加到此容器的尾部。Componentadd(Componentcomp,intindex)

314、将指定组件添加到此容器的给定位置上。voidremove(Componentcomp)从此容器中移除指定组件。voidremove(intindex)从此容器中移除index指定的组件。voidremoveAll()从此容器中移除所有组件。voidaddContainerListener(ContainerListenerl)添加指定容器的侦听器,以接收来自此容器的容器事件。LayoutManagergetLayout()获得此容器的布局管理器。voiddoLayout()使此容器布置其组件。ComponentfindComponentAt(intx,inty)对包含指定位置的可视子组件进行定

315、位。ComponentgetComponent(intn)获得此容器中的第n个组件。ComponentgetComponentAt(intx,inty)获取在点(x,y)位置的组件。intgetComponentCount()获得此面板中的组件数。ComponentgetComponents()获得此容器中的所有组件。ContainerListenergetContainerListeners()返回已在此容器上注册的所有容器侦听器的数组。voidremoveContainerListener(ContainerListenerl)移除指定容器的侦听器,从而不再接收来自此容器的容器事件。容器概

316、念Swing提供了四种顶层容器,它们分别是JWindow、JDialog、JFrame和JApplet。它们共有的相同的主要方法:ContainergetContentPane()返回此窗体的contentPane对象voidsetContentPane(ContainercontentPane)设置contentPane属性。JRootPanegetRootPane()返回此窗体的rootPane对象。protectedvoidsetRootPane(JRootPaneroot)设置rootPane属性。ComponentgetGlassPane()返回此窗体的glassPane对象。voi

317、dsetGlassPane(ComponentglassPane)设置glassPane属性。JLayeredPanegetLayeredPane()返回此窗体的layeredPane对象。JLayeredPanesetLayeredPane()设置此窗体的layeredPane对象。intgetDefaultCloseOperation()返回用户在此窗体上发起关闭时执行的操作。voidsetDefaultCloseOperation(intoperation)设置用户在此窗体上发起关闭时默认执行的操作。JMenuBargetJMenuBar()返回此窗体上设置的菜单栏。voidsetJMe

318、nuBar(JMenuBarmenubar)设置此窗体的菜单栏。voidremove(Componentcomp)从该容器中移除指定组件。voidsetIconImage(Imageimage)设置此frame要显示在最小化图标中的图像。容器概念例11-2使用JFrame创建一个简单Hello应用程序(HelloJFrame类),如右图所示。1publicclassHelloJFrame2publicstaticvoidmain(Strings)3/创建窗口实例,并设置标题创建窗口实例,并设置标题4JFramef=newJFrame(hello系统系统);5/创建按钮实例创建按钮实例6JBut

319、tonb=newJButton(进入系统进入系统);7Containerc=null;8JLabellb=newJLabel(欢迎使用本系统欢迎使用本系统);9/设置标签的字体颜色为蓝色设置标签的字体颜色为蓝色10lb.setForeground(Color.BLUE);11/得到得到JFrame中的中的conentPane对象对象,返回返回Container对象对象12c=f.getContentPane();13/将标签对象将标签对象lb放入放入Container对象对象c中心,中心,14c.add(lb,BorderLayout.CENTER);/将标签将标签lb放到窗口的中部放到窗口的

320、中部15c.add(b,BorderLayout.EAST);/将按钮对象将按钮对象b放到窗口东边放到窗口东边16f.setSize(300,200);/设置窗口对象设置窗口对象f的大小的大小17f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);18f.setVisible(true);/显示窗口显示窗口1920返回目录11.3窗格概念(1)根窗格:它是在JFrame窗体创建时就自动添加进来的,是所有其他窗格的载体,它覆盖窗体的除标题栏和边条之外的整个表面。根窗格在默认情况下是不可见的。根窗格负责管理其他窗格(层窗格,玻璃窗格),如使其他窗格覆盖

321、整个JFrame窗体等。(2)层窗格:它是其他窗格的父级窗格,在根窗格的上面。它再次覆盖窗体的整个表面,内容窗格和菜单栏被添加到层窗格上。当添加了菜单栏时,菜单栏被添加到层窗格的顶部,剩下的部分被内容窗格填充。层窗格是分很多层的,每一层使用一个相应的数字来表示,而内容窗格就位于层窗格中的某一层。(3)内容窗格:内容窗格是层窗格中的某一层。默认的内容窗格是不透明的,而且是一个JPane对象。该窗格在窗体中起着工作区的作用,当向窗体添加组件时就应该添加到这一层上,而不能像AWT那样直接添加到窗体上。实际上该组件也是被添加到内容窗格上的,若窗体未设置内容窗格,则组件无法显示。(4)玻璃窗格:该窗格总

322、是存在的,而且它位于最上面,默认情况下玻璃窗格是不可见的,玻璃窗格用于接收鼠标事件和在其他组件上绘图。(5)JPanel窗格:它是一个容器,可以在它之上放置按钮、滑块等组件,可以在它之上绘图。窗格举例例11-3关于窗格的应用程序,本例程序运行结果如图11-5所示。1、定义显示文字信息窗格、定义显示文字信息窗格MessagePanel类。类。1classMessagePanelextendsJPanel2/重载方法重载方法3protectedvoidpaintComponent(Graphicsg)4super.paintComponent(g);5g.drawString(消息窗格消息窗格,1

323、0,20);67窗格举例1classPanelFrameextendsJFrame2privatestaticfinalintDEFAULT_WIDTH=500;3privatestaticfinalintDEFAULT_HEIGHT=300;4publicPanelFrame()5setTitle(消息框架消息框架);6setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);/设置框架大小设置框架大小7MessagePanelpanel=newMessagePanel();/给框架添加窗格给框架添加窗格8add(panel);9setVisible(true);1011p

324、ublicstaticvoidmain(Stringargs)12PanelFrameframe=newPanelFrame();13frame.setVisible(true);/显示框架显示框架141511.4布局管理器概念6种布局管理器分别是FlowLayout、BorderLayout、BoxLayout、GirdBagLayout、GirdLayout和CardLayout。其中CardLayout必须和其他5种配合使用,不是特别常用的。应该注意以下两点:(1)容器中的布局管理器负责各个组件的大小和位置,因此用户无法在这种情况下设置组件的这些属性。如果试图使用Java语言提供的set

325、Location(),setSize(),setBounds()等方法,则都会被布局管理器覆盖。(2)如果用户确实需要亲自设置组件大小或位置,则应取消该容器的布局管理器,方法为setLayout(null);流式布局管理器流式布局管理器(FlowLayout)把容器看成一个行集,一行填满了,再填下一行。每行行高是由该行中的控件高度所决定。流式布局管理器是窗格(Panel)和所有JApplet的默认布局。FlowLayout的构造方法如下:FlowLayout()生成一个默认的流式布局,组件在容器里居中,每个组件之间留下5个像素的距离.FlowLayout(intalignment)可以设定每行

326、组件的对齐方式.流式布局管理器例例11-4下面是使用了流式布局管理器管理按钮控件。下面是使用了流式布局管理器管理按钮控件。1publicclassFlowJFrame2publicstaticvoidmain(Strings)3/创建窗口实例,并设置标题创建窗口实例,并设置标题4JFramef=newJFrame(流式布局管理器例子流式布局管理器例子);5Containerc=null;6/得到得到JFrame中的中的conentPane对象对象,返回返回Container对象对象7c=f.getContentPane();8FlowLayoutflowlayout=newFlowLayout

327、();/容器默认的对齐方式容器默认的对齐方式(FlowLayout.CENTER)9flowlayout.setAlignment(FlowLayout.RIGHT);/设置右对齐方式设置右对齐方式10c.setLayout(flowlayout);11/创建按钮数组,数组大小为创建按钮数组,数组大小为912JButtonb=newJButton9;13inti;14for(i=0;i9;i+)1516bi=newJButton(按钮按钮+i);17bi.setBackground(Color.LIGHT_GRAY);/设置按钮的背景颜色设置按钮的背景颜色18c.add(bi);/加入按钮加入

328、按钮Container对象对象1920f.setSize(600,200);/设置窗口对象设置窗口对象f的大小的大小21f.setVisible(true);/显示窗口显示窗口2223流式布局管理器 (2)RIGHT对齐方式(1)CENTER对齐方式 (3)LEFT对齐方式(4)Trailing对齐方式(5)Leading对齐方式边界布局管理器边界布局管理器(BorderLayout)是一种非常简单的布局策略。它把容器内的空间简单地划分为东、西、南、北、中五个区域,当加入一个组件都应该指明把这个组件放在哪个区域中,默认的情况是加入到中间。但是,不一定所有的区域都必须有组件,如果四周的区域(We

329、st、East、North、South区域)没有组件,则由Center区域去补充。如果Center区域也没有组件,则容器保持空白.BorderLayout是顶层容器JFrame、JDialog以及JApplet的默认布局管理器。BorderLayout的构造方法如下:BorderLayout()构造一个组件之间没有间构造一个组件之间没有间距的新边界布局。距的新边界布局。BorderLayout(inth,intv)用指定的组件用指定的组件之间的水平间距构造一个边界布局。之间的水平间距构造一个边界布局。边界布局管理器例11-5边界管理器布局程序示例。1publicclassBorderJFram

330、e2publicstaticvoidmain(Strings)3/创建窗口实例,并设置标题创建窗口实例,并设置标题4JFramef=newJFrame(边界布局管理器边界布局管理器);5Containerc=null;6/得到得到JFrame中的中的conentPane对象对象,返回返回Container对象对象7c=f.getContentPane();8c.setLayout(newBorderLayout();9Stringdirection=BorderLayout.EAST,BorderLayout.SOUTH,10BorderLayout.WEST,BorderLayout.NOR

331、TH,BorderLayout.CENTER;11/创建按钮数组,数组大小为创建按钮数组,数组大小为512JButtonb=newJButton5;13for(inti=0;i5;i+)14bi=newJButton(按钮按钮+Integer.toString(i);15bi.setBackground(Color.LIGHT_GRAY);16c.add(bi,directioni);1718f.setSize(200,200);/设置窗口对象设置窗口对象f的大小的大小19f.setVisible(true);/显示窗口显示窗口2021网格布局管理器网格布局管理器(GridLayout)将成员

332、按网格型排列,每个成员尽可能地占据网格的空间,每个网格也同样尽可能地占据空间,从而各个成员按一定的大小比例放置。如果你改变大小,GridLayout将相应地改变每个网格的大小,以使各个网格尽可能地大,占据Container容器全部的空间。GridLayout的构造方法如下:GridLayout()创建具有默认值的网格布局,即每个组件占据一行一列。GridLayout(intr,intc)创建具有指定行数r和列数c的网格布局。另外,我们可以通过下面两个方法来改变网格布局中的行列数。voidsetColumns(intc)设置布局中的列数为c。void setRows(intr)设置布局中的行数为

333、r。网格布局管理器网格布局管理器例11-6网格布局举例。1publicclassGridJFrame2publicstaticvoidmain(Strings)3/创建窗口实例,并设置标题创建窗口实例,并设置标题4JFramef=newJFrame(网格布局管理器网格布局管理器);5Containerc=null;6/得到得到JFrame中的中的conentPane对象对象,返回返回Container对象对象7c=f.getContentPane();8c.setLayout(newGridLayout(5,4);/5行行4列网格列网格9/创建按钮数组,数组大小为创建按钮数组,数组大小为510

334、JButtonb=newJButton9;11for(inti=0;i9;i+)12bi=newJButton(按钮按钮+Integer.toString(i);13bi.setBackground(Color.LIGHT_GRAY);14c.add(bi);1516f.setSize(200,200);/设置窗口对象设置窗口对象f的大小的大小17f.setVisible(true);/显示窗口显示窗口1819卡式布局管理器卡式布局管理器(CardLayout)能够帮助用户处理两个及更多的成员共享同一显示空间,它把容器分成许多层,每层的显示空间占据整个容器的大小,但是每层只允许放置一个组件,当

335、然每层都可以利用Panel来实现复杂的用户界面.布局管理器(CardLayout)就象一副叠得整整齐齐的卡片,但是我们只能见到最上面的一张,一张卡片就相当于布局管理器中的每一层。CardLayout的构造方法如下:CardLayout()创建一个间隙大小为0的新卡片布局。CardLayout(inthgap,intvgap)创建一个具有指定的水平和垂直间隙的新卡片布局。返回目录11.5Java事件处理java中的事件处理机制的参与者有3种角色:事件对象(EventObject):可将它作为事件监听者相应方法的参数。事件源(EventSource):具体操作的对象。比如点击一个按钮,那么该按钮就

336、是事件源。事件监听者或者事件监听器或者事件适配器(eventlistener):实现事件监听接口中部分或全部方法的类就是事件监听者。在Java事件处理过程中,伴随着事件的发生,相应的状态通常都封装在事件状态对象中,该对象必须继承自java.util.EventObject。根据EventObject的定义(publicclassEventObjectextendsObjectimplementsSerializable),所有事件对象在构造时都引用了对象。对每个明确的事件的发生,都相应地定义一个明确的方法。这些方法都集中定义在事件监听者(EventListener)接口中,这个接口继承于jav

337、a.util.EventListener。Java事件处理Java的事件处理机制是:(1)操作者在事件源上触发事件操作,即调用firexxxx()方法;例如,单击按钮,将调用按钮单击事件;(2)firexxxx()方法创建事件对象,说明该事件已经发生了,然后通知事件监听者(或者叫做事件适配器);(3)由于事件监听者实现了事件监听接口中的方法,事件监听者根据事件调用事件监听接口中的方法。(4)只有与所触发事件关联的事件监听者调能用事件处理方法。Java事件处理过程举例例11-8通过汽车换挡处理来演示Java事件处理过程。(1)汽车换挡操作事件汽车换挡操作事件ShiftEvent类。类。1publ

338、icclassShiftEventextendsEventObject2StringshiftState;/汽车换挡状态D,D1,D2,P,R3publicShiftEvent(Objectsource,StringshiftState)4super(source);/调用EventObject构造方法,初始化父类5this.shiftState=newString(shiftState);67/得到汽车换挡状态8publicStringgetShiftState()9returnshiftState;1011Java事件处理过程举例(续)(2)换挡监听接口换挡监听接口ShiftListene

339、r。importjava.util.EventListener;1publicinterfaceShiftListenerextendsEventListener2publicvoidshiftEvent(ShiftEvente);3(3)监控换到档位监控换到档位D1的事件监控器。的事件监控器。1publicclassShiftListenerD1AdapterimplementsShiftListener2Override3publicvoidshiftEvent(ShiftEvente)4if(e.getShiftState()!=null&e.getShiftState().compar

340、eTo(D1)=0)5System.out.println(换到档位+D1);67Java事件处理过程举例(续)(4)监控换到档位监控换到档位D2的事件监控器。的事件监控器。1publicclassShiftListenerD2AdapterimplementsShiftListener2Override3publicvoidshiftEvent(ShiftEvente)4if(e.getShiftState()!=null&e.getShiftState().equals(D2)5System.out.println(换到档位+D2);67(5)监控换到档位监控换到档位D的事件监控器。的事件

341、监控器。1publicclassShiftListenerDAdapterimplementsShiftListener2Override3publicvoidshiftEvent(ShiftEvente)4if(e.getShiftState()!=null&e.getShiftState().equals(D)5System.out.println(换到档位+D);67Java事件处理过程举例(续)(7)监控换到档位监控换到档位R的事件监控器。的事件监控器。1publicclassShiftListenerDAdapterimplementsShiftListener2Override3p

342、ublicvoidshiftEvent(ShiftEvente)4if(e.getShiftState()!=null&e.getShiftState().equals(R)5System.out.println(换到档位+R);67Java事件处理过程举例(续)(8)档位操作杆类档位操作杆类ShiftMananger1publicclassShiftManager2privateCollectionlisteners=null;3publicShiftManager()4listeners=newHashSet();5/加入换挡操作事件的监视器加入换挡操作事件的监视器6this.addShi

343、ftListener(newShiftListenerD1Adapter();7this.addShiftListener(newShiftListenerD2Adapter();8this.addShiftListener(newShiftListenerDAdapter();9this.addShiftListener(newShiftListenerPAdapter();10this.addShiftListener(newShiftListenerRAdapter();1112/添加监视器添加监视器13publicvoidaddShiftListener(ShiftListenerli

344、stener)14if(listeners=null)15listeners=(newHashSet();1617listeners.add(listener);1819/删除监视器删除监视器20publicvoidremoveShiftListener(ShiftListenerlistener)21listeners.remove(listener);22Java事件处理过程举例(续)23/触发到转到D1事件24protectedvoidfireShiftD1()25ShiftEventshiftEvent=newShiftEvent(this,D1);26notifyListeners(

345、shiftEvent);2728/触发转到D2档事件29protectedvoidfireShiftD2()30ShiftEventshiftEvent=newShiftEvent(this,D2);31notifyListeners(shiftEvent);3233/触发转到D档事件34protectedvoidfireShiftD()35ShiftEventshiftEvent=newShiftEvent(this,D);36notifyListeners(shiftEvent);3738/触发转到P档事件39protectedvoidfireShiftP()40ShiftEventshi

346、ftEvent=newShiftEvent(this,P);41notifyListeners(shiftEvent);42Java事件处理过程举例(续)43/触发转到D档事件44protectedvoidfireShiftR()45ShiftEventshiftEvent=newShiftEvent(this,R);46notifyListeners(shiftEvent);/*通知所有的事件监听者*/4748/*49*通知所有事件监听者*/50privatevoidnotifyListeners(ShiftEvente)51Iteratoriter=listeners.iterator()

347、;52/iter是事件监听者,由于只需要调用其事件监听接口中的方法,不考虑它是何种事件监听者53/所以下面只需要定义事件监听者接口就行了。54while(iter.hasNext()55ShiftListenerlistener=(ShiftListener)iter.next();56listener.shiftEvent(e);575859Java事件处理过程举例(续)(9)定义Driver类,该类对象相当于驾驶员,他操作档位换挡杆ShiftMananger对象。21System.out.println(找到停车位置找到停车位置);22/换到档位换到档位R23shiftManager.fi

348、reShiftR();24System.out.println(将车停好将车停好);25/换到档位换到档位P26shiftManager.fireShiftP();27System.out.println(车熄火车熄火);2829publicstaticvoidmain(Stringargs)30Driverdriver=newDriver();31driver.operateBus();3233341publicclassDriver2publicvoidoperateBus()3ShiftManagershiftManager=newShiftManager();4System.out.p

349、rintln(点火启动汽车:点火启动汽车:);5System.out.println(慢慢松开刹车板慢慢松开刹车板);6/换到档位换到档位D17shiftManager.fireShiftD1();8System.out.println(完全松开刹车板完全松开刹车板);9/换到档位换到档位D210shiftManager.fireShiftD2();11System.out.println(继续加速继续加速);12/换到档位换到档位D13shiftManager.fireShiftD();14System.out.println(运行一段时间后。运行一段时间后。);15/换到档位换到档位D21

350、6shiftManager.fireShiftD2();17System.out.println(减速减速);18/换到档位换到档位D119shiftManager.fireShiftD1();20System.out.println(靠路边慢慢行驶靠路边慢慢行驶);21System.out.println(找到停车位置找到停车位置);事件的种类事件的种类Java把事件类大致分为两种:底层事件和语义事件。其中直接继承来自于AWTEvent的事件,称之为语义事件,如AdjustmentEvent、ActionEvent以及ComponentEvent等。继承来自于ComponentEvent类的

351、事件是低级事件,如WindowEvent、KeyEvent、ContainerEvent、FocusEvent等。事件的种类事件名称事件名称事件说明事件说明触发条件触发条件ComponentEvent组件事件显示、移动、缩放或隐藏组件显示、移动、缩放或隐藏组件InputEvent输入事件键盘操作(按下键,或释放键)键盘操作(按下键,或释放键)MouseEvent鼠标事件鼠标操作(鼠标移动,按下,或释放)鼠标操作(鼠标移动,按下,或释放)FocusEvent焦点事件组件得到或失去焦点组件得到或失去焦点ContainerEvent容器事件向容器内增加、减少组件向容器内增加、减少组件WindowEv

352、ent窗口事件窗口事件窗口最大化、最小化、关闭等窗口最大化、最小化、关闭等低级事件列表低级事件列表事件的种类事件名称事件名称事件说明事件说明事件源事件源触发条件触发条件ActionEvent行为事件行为事件文文本本框框,按按钮钮,组组合合框框,定时器定时器点点击击按按钮钮;文文本本框框输输入入时时,按按下下回回车车键键;定定时器时间到;时器时间到;ItemEvent选项事件选项事件复复选选框框,单单选选按按钮钮,选选项,列表项,列表选择列表选项选择列表选项TextEvent文本事件文本事件文文本本框框,文文本区域本区域输入或改变文本内容输入或改变文本内容AdjustmentEvent调整事件调

353、整事件滚动条滚动条调整滚动条调整滚动条事件的种类事件类型事件类型接口名字接口名字接口中的方法接口中的方法ComponentEventComponentListenervoidcomponentHidden(ComponentEvente)voidcomponentMoved(ComponentEvente)voidcomponentResized(ComponentEvente)voidcomponentShown(ComponentEvente)ContainerEventContainerListenervoidcomponentAdded(ContainerEvente)componen

354、tRemoved(ContainerEvente)FocusEventFocusListenervoidfocusGained(FocusEvente)voidfocusLost(FocusEvente)KeyEventKeyListenervoidkeyPressed(KeyEvente)voidkeyReleased(KeyEvente)voidkeyTyped(KeyEvente)MouseEventMouseListenervoidmouseClicked(MouseEvente)voidmouseEntered(MouseEvente)voidmouseExited(MouseEve

355、nte)voidmousePressed(MouseEvente)voidmouseReleased(MouseEvente)MouseWheelEventMouseWheelListenermouseWheelMoved(MouseWheelEvente)常用的事件类型、与之对应的接口名字以及接口中的抽象方法常用的事件类型、与之对应的接口名字以及接口中的抽象方法事件的种类事件类型事件类型接口名字接口名字接口中的方法接口中的方法MouseEventMouseMotionListenervoidmouseDragged(MouseEvente)voidmouseMoved(MouseEvente

356、)WindowEventWindowListenervoidwindowActivated(WindowEvente)voidwindowClosed(WindowEvente)voidwindowClosing(WindowEvente)voidwindowDeactivated(WindowEvente)voidwindowDeiconified(WindowEvente)voidwindowIconified(WindowEvente)voidwindowOpened(WindowEvente)ActionEventActionListeneractionPerformed(Action

357、Evente)ItemEventItemListeneritemStateChanged(ItemEvente)TextEventTextListenertextValueChanged(TextEvente)AdjustmentEventAdjustmentListeneradjustmentValueChanged(AdjustmentEvente)AncestorAncestorListenervoidancestorAdded(AncestorEventevent)voidancestorMoved(AncestorEventevent)voidancestorRemoved(Ance

358、storEventevent)CaretEventCaretListenercaretUpdate(CaretEvente)ChangeEventChangeListenervoidstateChanged(ChangeEvente)DocumentEventDocumentListenervoidchangedUpdate(DocumentEvente)voidinsertUpdate(DocumentEvente)voidremoveUpdate(DocumentEvente)TreeExpansionEventTreeExpansionListenervoidtreeCollapsed(

359、TreeExpansionEventevent)voidtreeExpanded(TreeExpansionEventevent)TreeExpansionEventTreeWillExpandListenervoidtreeWillCollapse(TreeExpansionEventevent)voidtreeWillExpand(TreeExpansionEventevent)事件的种类例11-9定义进入系统按键处理的程序。1publicclassMyButtonextendsJButtonimplementsMouseListener2privateJLabellb;3MyButton

360、(Strings,JLabellb)4super(s);5this.lb=lb;6addMouseListener(this);/注册鼠标按键事件监听程序注册鼠标按键事件监听程序78/下面实现接口下面实现接口MouseListener中的方法。中的方法。9publicvoidmousePressed(MouseEvente)10publicvoidmouseReleased(MouseEvente)11publicvoidmouseEntered(MouseEvente)12publicvoidmouseExited(MouseEvente)13publicvoidmouseClicked(M

361、ouseEvente)14lb.setText(欢迎您进入系统,谢谢!欢迎您进入系统,谢谢!);1516事件的种类(2)Hello1类定义如下:类定义如下:1publicclassHello12publicstaticvoidmain(Strings)3/创建窗口实例,并设置标题创建窗口实例,并设置标题4JFramef=newJFrame(hello1系统系统);5JLabellb=newJLabel(欢迎使用本系统欢迎使用本系统);6/创建自定义按钮实例创建自定义按钮实例7MyButtonb=newMyButton(进入系统进入系统,lb);8Containerc=null;9/设置标签的字

362、体颜色为蓝色设置标签的字体颜色为蓝色10lb.setForeground(Color.BLUE);11/得到得到JFrame中的中的conentPane对象对象,返回内容窗格对象返回内容窗格对象12c=f.getContentPane();13/将标签对象将标签对象lb放入放入Container对象对象c中心,中心,14c.add(lb,BorderLayout.CENTER);/将标签将标签lb放到窗口的中部放到窗口的中部15c.add(b,BorderLayout.EAST);/将按钮对象将按钮对象b放到窗口东边放到窗口东边16f.setSize(300,200);/设置窗口对象设置窗口对

363、象f的大小的大小17f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);18f.setVisible(true);/显示窗口显示窗口192021事件适配器事件适配器实现了形如XListener接口的抽象类,同时实现了XListener接口中的方法,且这些方法是空的。例如,在Java语言中,存在实现了KeyListener接口的事件适配器KeyAapter,其定义如下:publicabstractclassKeyAdapterextendsObjectimplementsKeyListener /按下某个键时调用此方法。voidkeyPressed(

364、KeyEvente)/释放某个键时调用此方法。voidkeyReleased(KeyEvente)/键入某个键时调用此方法。voidkeyTyped(KeyEvente)事件适配器在Java语言中,常用的事件适配器如下表所示。事件适配器名称事件适配器名称说明说明实现接口名称实现接口名称ComponentAdapter接收组件事件的抽象适配器类ComponentListenerContainerAapter接收容器事件的抽象适配器类ContainerListenerFocusAdapter接收键盘焦点事件的抽象适配器类FocusListenerKeyAdapter接收键盘事件的抽象适配器类Key

365、ListenerMouseAdapter接收鼠标事件的抽象适配器类MouseListenerMouseMotionAapter接收鼠标移动事件的抽象适配器类MouseMotionListenerWindowAdapter接收窗口事件的抽象适配器类WindowListenerAbstractActionJFCAction接口的默认实现接口的默认实现ActionListener事件适配器举例例11-10编写窗体应用程序,输入三角形的三条边长,求面积。(1)自定义按钮适配器ButtonAdapterOfTriangle。1publicclassButtonAdapterOfTriangleexten

366、dsMouseAdapter2privateAreaOfTrianglef;3publicButtonAdapterOfTriangle(AreaOfTrianglef)4this.f=f;56Override7publicvoidmouseClicked(MouseEvente)8doublea=newdouble3;9JTextFieldjt=f.jt;10inti;11try12for(i=0;i3;i+)13ai=Double.valueOf(jti.getText().trim();1415catch(Exceptionee)16f.result.setText(没有输入数据或者输入

367、数据不合法!);17return;1819/定义三角形对象20Triangle11t=newTriangle11(a0,a1,a2);21/如果是三角形时22if(t.isTriangle()23f.result.setText(t.toString();2425else26f.result.setText(t.toString();2728事件适配器举例(2)自定义按钮ButtonOfTriangle。1publicclassButtonOfTriangleextendsJButton2privateAreaOfTrianglef;3publicButtonOfTriangle(String

368、s,AreaOfTrianglef)4super(s);5this.f=f;6this.addMouseListener(newButtonAdapterOfTriangle(f);/注册事件适配器78事件适配器举例(3)求三角形面积类求三角形面积类AreaOfTriangle。1publicclassAreaOfTriangle2JLabellb=newJLabel(输入三角形的三条边长输入三角形的三条边长:);3JLabelresult=newJLabel(面积是:面积是:);4JTextFieldjt=newJTextField3;5privateJFramef;6privateButt

369、onOfTriangleb=newButtonOfTriangle(求面积求面积,this);7publicAreaOfTriangle()8f=newJFrame();9f.setTitle(求三角形的面积求三角形的面积);10Containerc=f.getContentPane();11c.setLayout(newGridLayout(3,1);/3行行1列网格列网格12JPanelp1=newJPanel();13p1.setLayout(newGridLayout(1,12);/1行行12列网格列网格14p1.add(lb);15for(inti=0;ijt.length;i+)1

370、6jti=newJTextField();17p1.add(jti);1819c.add(p1);20c.add(result);21JPanelp2=newJPanel();22p2.setLayout(newGridLayout(1,3);/1行12列网格23c.add(p2);24p2.add(newJLabel();25p2.add(b);26p2.add(newJLabel();27f.setSize(1000,200);/设置窗口对象f的大小28setFont(楷体,18);/设置窗体上所有控件字体29f.setDefaultCloseOperation(JFrame.EXIT_O

371、N_CLOSE);30f.setVisible(true);/显示窗口31事件适配器举例32/设计界面控件上字体设计界面控件上字体33publicvoidsetFont(StringfontName,intsize)34Fontfont=newFont(fontName,Font.PLAIN,size);35inti;36lb.setFont(font);37for(i=0;ijt.length;i+)38jti.setFont(font);39result.setFont(font);40b.setFont(font);4142publicstaticvoidmain(Stringargs)

372、43AreaOfTrianglea=newAreaOfTriangle();44本章结束!第12章Swing组件编程本章内容12.1Swing包的介绍12.2分析Netbeans环境下的Swing应用程序12.3常用对话框12.4Swing下的常用控件类的使用12.5菜单组件12.6工具栏12.7表格12.1Swing包的介绍Swing组件是从AWT组件继承拓展而来的。它绝大多数组件类名是以大写字母J开头。例如,JLabel、JLayeredPane、JList、JMenuBar等。Swing组件是轻量级组件,它没有本地代码又无需操作系统的支持。与之相反,AWT组件中的图形方法与操作系统所提供

373、的图形方法之间存在一一对应的关系。Swing组件程序运行速度比AWT组件程序要慢一些。另外,Swing组件跟AWT组件的事件处理机制相同。Swing组件的类层次图Swing组件分类按功能分类,Swing组件包括5类组件:(1)顶层容器,如,JWindow、JFrame、JDialg以及JApplet。(2)Swing容器,如,JPanel、JOptionPane、JScrollPane、LayeredPane、JRootPane等。(3)Swing控件,如,JTextField、JButton、JLabel以及JList。(4)Swing菜单,JMenuBar、JPopupMenu等。(5)S

374、wingFiller组件,它们参与布局但没有视图的轻量级组件。(6)Swing窗口,如对话框、颜色选择器、文件选择器等。在NetbeanIDE开发环境下,组件面板布局如右图所示。返回目录12.2Netbeans环境下的Swing应用程序例12-1创建Swing应用程序HelloSystem程序。(1)新建文件时,选择类别为SwingGUI窗体,文件类型为JFrame窗体,如图12-3所示。此处建立了窗体应用程序HelloSystem。Netbeans环境下的Swing应用程序(2)在设计模式下,可以通过拖放方式,从右边的组件面板上把需要的各种组件放到窗体上来。Netbeans环境下的Swing

375、应用程序(3)设置各组件的具体属性。选择某个组件,右单击后在弹出菜单中选择属性选项,进入属性窗口。Netbeans环境下的Swing应用程序(4)设置各组件的关联事件,设置“进入系统”按钮的事件,Netbeans环境下的Swing应用程序(5)在代码设计模式下,编写事件处理方法。public class HelloSystem extends javax.swing.JFrame private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) JFrame f=new JFrame(); JOptionPane.show

376、MessageDialog(f, 你已你已进入了入了HelloSystem!); Netbeans环境下的Swing应用程序(6)当设计界面以及代码编写完成后,可以编译并运行程序了。Netbeans环境下的Swing应用程序HelloSystem窗体程序代码说明如下:publicclassHelloSystemextendsjavax.swing.JFramepublicHelloSystem()/构造方法,初始化应用程序界面构造方法,初始化应用程序界面initComponents();/*该方法仅由构造方法调用,而且不能在代码模式下修改该方法,进行窗体设计完成后,该方该方法仅由构造方法调用,

377、而且不能在代码模式下修改该方法,进行窗体设计完成后,该方法内容由系统自动产生。法内容由系统自动产生。*/privatevoidinitComponents()/编写按下编写按下“进入系统进入系统”按钮后的事件处理程序。按钮后的事件处理程序。privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)JFramef=newJFrame();/调用调用JOptionPane类提示框一常用方法类提示框一常用方法JOptionPane.showMessageDialog(f,你已进入了你已进入了HelloSystem!);/在设计时

378、加入的组件,是应用程序类的私有属性。在设计时加入的组件,是应用程序类的私有属性。privatejavax.swing.JButtonjButton1;privatejavax.swing.JLabeljLabel1;Netbeans环境下的Swing应用程序(b)initComponents方法,该方法由系统自动产生,编程者无法直接编辑该方法中的代码,但编程者进行界面设计,界面设计结果都会在此方法中产生相应代码。privatevoidinitComponents()/初始化窗体上的组件对象jLabel1=newjavax.swing.JLabel();pack();/Netbeans环境下的S

379、wing应用程序(c)设置应用程序外观和感觉Netbean提供的外观样式有提供的外观样式有:Metal、Nimbus、CDE/Motif、Windows、WindowsClassicpublicstaticvoidmain(Stringargs)tryfor(javax.swing.UIManager.LookAndFeelInfoinfo:javax.swing.UIManager.getInstalledLookAndFeels()if(Nimbus.equals(info.getName()/*设置Nimbus外观和感觉样式*/javax.swing.UIManager.setLookA

380、ndFeel(info.getClassName();break;Netbeans环境下的Swing应用程序(d)在界面设计时,编程者在界面设计模式下添加的组件,系统都会在类尾部声明组件对象变量。 (e)最后,执行下面代码,其作用是创建窗体并显示窗体界面。java.awt.EventQueue.invokeLater(newRunnable()publicvoidrun()newHelloSystem().setVisible(true););返回目录12.3常用对话框JOptionPane类的作用是:要求用户输入数据或向用户发出通知标准对话框。(1)showConfirmDialog:询问一

381、个确认问题,如yes/no/cancel。showConfirmDialog方法的定义形式如下:staticint showConfirmDialog(ComponentparentComponent,Objectmessage,Stringtitle,intoptionType,intmessageType,Iconicon);(2)showInputDialog:提示要求某些输入。方法的定义形式如下:showInputDialog(ComponentparentComponent,Objectmessage,Stringtitle,intmessageType,Iconicon,Objec

382、tselectionValues,ObjectinitialSelectionValue);(3)showMessageDialog通知用户某件事已经发生。showMessageDialog方法定义形式如下:staticvoidshowMessageDialog(ComponentparentComponent,Objectmessage,Stringtitle,intmessageType,Iconicon)(4)showOptionDialog:它是上面(1)、(2)、(3)的综合。showOptionDialog方法的定义形式如下:staticintshowOptionDialog(Co

383、mponentparentComponent,Objectmessage,Stringtitle,intoptionType,intmessageType,Iconicon,Objectoptions,ObjectinitialValue)常用对话框(续)(1)parentComponent参数:它作为此对话框的父对话框的 Component。该参数可以是null,在这种情况下,默认的Frame用作父级,并且对话框将居中位于屏幕上(取决于L&F)。message参数:它是要置于对话框中的描述消息。在最常见的应用中,message 就是一个 String 或 String 常量。不过,此参数的类

384、型实际上是Object,其解释依赖于其类型。(2)Object参数:它是纵向堆栈中排列的一系列 message(每个对象一个)。解释是递归式的,即根据其类型解释数组中的每个对象。(3)Component参数:它是在在对话框中显示的组件。(4)Icon参数:它是被包装在 JLabel中并且在对话框中显示的图标。(5)messageType参数:定义message的样式。外观管理器布置的对话框可能因此值而异,并且往往提供默认图标。可能的值为:INFORMATION_MESSAGE、ERROR_MESSAGE、QUESTION_MESSAGE、PLAIN_MESSAGE以及WARNING_MESSA

385、GE。(6)optionType参数:它是定义在对话框的底部显示的选项按钮集合。其值可以是:DEFAULT_OPTION、YES_NO_CANCEL_OPTION、OK_CANCEL_OPTION、YES_NO_OPTION。用户并非仅限于使用选项按钮的此集合。使用 options 参数可以提供想使用的任何按钮。(7)Options参数:它对将在对话框底部显示的选项按钮集合进行的更详细描述。options 参数的常规值是 String 数组,但是参数类型是 Object 数组。根据对象的以下类型为每个对象创建一个按钮:(8)title参数: 它是对话框的标题。(9)initialValue参数

386、:它是对话框中的默认的输入值。常用对话框举例例12-2显示你喜欢水果对话框,并显示你所选择选项。1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2intselect;3/窗口标题是:选择一个选项4select=JOptionPane.showConfirmDialog(null,你喜欢水果吗);5Stringmsg=没有选择;6switch(select)7caseJOptionPane.OK_OPTION:8msg=你喜欢水果。;break;9caseJOptionPane.CANCEL_OPTION:10m

387、sg=你没有选择哦。;break;11caseJOptionPane.NO_OPTION:12msg=你不喜欢水果。;break;1314JOptionPane.showMessageDialog(null,msg);/显示选择结果15例12-3显示一个错误信息对话框,该对话框显示的消息为“输入边长不构成三角形”,运行情况如图12-10所示。privatevoidjButton2ActionPerformed(java.awt.event.ActionEventevt)JOptionPane.showMessageDialog(null,不构成三角形,错误信息,JOptionPane.ERRO

388、R_MESSAGE);例12-4显示一个信息面板,其按钮选项为“yes/no”,其消息是“你是否喜欢编程”,运行情况如下图所示。privatevoidjButton3ActionPerformed(java.awt.event.ActionEventevt)JOptionPane.showConfirmDialog(null,你是否喜欢编程,爱好选择,JOptionPane.YES_NO_OPTION);例12-5显示一个输入信息对话框,消息是“你喜欢什么水果?”。然后将输入的信息显示出来,运行情况如下图所示。1privatevoidjButton4ActionPerformed(java.a

389、wt.event.ActionEventevt)2Stringmsg;3Stringresult;4result=JOptionPane.showInputDialog(null,你喜欢什么水果?);5msg=你喜欢的水果是:+result+哦;6if(result!=null&!result.trim().equals()7msg=你喜欢的水果是:+result+哦;8else9msg=你喜欢的水果是:+没有选择哦;10JOptionPane.showMessageDialog(null,msg);11例12-6显示一个警告对话框,其按钮选项为OK、CANCEL,标题为 “注意”,消息为 “

390、单击是继续”,运行情况如下图所示。privatevoidjButton5ActionPerformed(java.awt.event.ActionEventevt)Objectoptions=是,取消;JOptionPane.showOptionDialog(null,单击是继续,注意,JOptionPane.DEFAULT_OPTION,JOptionPane.WARNING_MESSAGE,null,options,options0);例12-7显示一个要求用户键入字符串的对话框,运行情况如下图所示。privatevoidjButton6ActionPerformed(java.awt.e

391、vent.ActionEventevt)StringinputValue=JOptionPane.showInputDialog(请输入:);JOptionPane.showMessageDialog(null,你输入的数据是:+inputValue);例12-8显示一个要求用户选择图形类别的对话框,运行情况如下图所示。例12-9显示一个内部信息对话框,其 options为JOptionPane.DEFAULT_OPTIONyes/no/cancel,message消息是“你是否爱唱歌”,并且对话框标题是“爱好请选择”,运行情况如图12-16所示。privatevoidjButton7Acti

392、onPerformed(java.awt.event.ActionEventevt)JFrameframe=newJFrame();frame.setSize(300,400);frame.setVisible(true);JInternalFramejf=newJInternalFrame();frame.add(jf);jf.setVisible(true);JOptionPane.showInternalMessageDialog(jf,你是否爱唱歌,爱好选择,JOptionPane.INFORMATION_MESSAGE);返回目录12.4Swing下的常用控件类的使用字体和颜色Jav

393、a提供的字体类Font和颜色类Color不属于Swing控件,而属于AWT组件。但而Swing控件又没有定义新的字体类和颜色类,所以Swing控件仍然沿用AWT中的字体和颜色类。JComponent类Swing的JComponent类是一个抽象类下面列出JComponent的一些主要方法,而且其子类都可以调用这些方法。voidadd(JComponentjc),可以添加其它的JComponent组件。JRootPanegetRootPane(),返回根窗格。StringgetToolTipText()返回组件提示信息。voidpaint(Graphicsg),由Swing发起的绘制组件。voi

394、dsetBackground(Colorbg)设置背景颜色。voidsetBorder(Borderborder)设置组件边界。voidsetEnabled(booleanenabled)设置组件是否可见。voidsetFont(Fontfont)设置组件字体。voidsetForeground(Colorfg)设置组件前景颜色。voidsetOpaque(booleanisOpaque)设置前景是否透明。voidsetVisible(booleanaFlag)设置组件是否可见。voidrequestFocus()请求此组件获得输入焦点。标签和图像图标标签标签的主要作用是显示提示性信息,通常用

395、来标注一些本身不具有标题属性的控件,例如用标签来描述文本框、组合框、列表框等控件附加信息。Swing组件中的标签类是JLabel。该类的主要构造方法如下:JLabel对象可以显示文本、图像或同时显示二者。JLabel()创建无图像并且其标题为空字符串的JLabel。JLabel(Iconimage)创建具有指定图像的JLabel实例。JLabel(Stringtext)创建具有指定文本的JLabel实例。JLabel(Stringtext,Iconicon,inth)创建指定文本、图像和水平对齐方式的JLabel实例。getText()/setText():获取/设置标签的文本。getIcon

396、()()/setIcon():获取/设置标签的图片。getHorizontalAlignment()/setHorizontalAlignment():获取/设置文本的水平位置。getDisplayedMnemonic/setDisplayedMnemonic():获取/设置标签的访问键(下划线文字)。getLableFor/setLableFor():获取/设置这个标签附着的组件,所以当用户按下Alt+访问键时,焦点转移到指定的组件。 2.图像位图Java提供了图像位图类是ImageIcon,其作用是根据Image绘制Icon。ImageIcon类的构造方法如下:ImageIcon()创建一

397、个未初始化的图像图标。ImageIcon(byteimageData)根据字节数组创建一个ImageIcon,这些字节读取自一个包含受支持图像格式(比如GIF、JPEG或从1.3版本开始的PNG)的图像文件。ImageIcon(byteimageData,Stringdescription)根据字节数组创建一个ImageIcon,这些字节读取自一个包含受支持图像格式(比如GIF、JPEG或从1.3版本开始的PNG)的图像文件。ImageIcon(Imageimage,Stringdescription)根据图像创建一个ImageIcon。ImageIcon(Stringfilename,Str

398、ingdescription)根据指定的文件创建一个ImageIcon。ImageIcon(URLlocation,Stringdescription)根据指定的URL创建一个ImageIcon。图像位图如果要将标签设为图像标签,则需要做两件事:(1)创建图像位图ImageIcon对象;(2)调用标签的setIcon()方法,装载该图像位图对象,当参数为null时,则取消标签的图像。例12-10创建窗体应用程序(LabelFrame类),该程序是关于标签的例子,其界面设计如图下所示。图像位图(1)设置标签文字按钮的ActionPerformed事件代码如下:1privatevoidjButto

399、n1ActionPerformed(java.awt.event.ActionEventevt)2StringinputValue=JOptionPane.showInputDialog(请输入文字:);3jLabel1.setText(inputValue);4jLabel1.setIcon(null);5this.setTitle(将标签设为文字);6(2)设置图片按钮的ActionPerformed事件代码如下:1privatevoidjButton2ActionPerformed(java.awt.event.ActionEventevt)2ImageIconimg=newImageI

400、con(E:2018JavaBookcode12Swing组件imageschair.jpg);3jLabel1.setIcon(img);4this.setTitle(将标签设为图片);512.4.4按钮Java按钮主要包括简单按钮、单选按钮和复选按钮。1.简单按钮JButton是最简单的按钮。其构造方法如下:JButton()创建按钮,但没有设置名称和按钮图标。JButton(Actiona)创建按钮,所具有属性是由类型为Action的参数a提供的。JButton(Iconicon)创建带有图标的按钮JButton(Stringtext,Iconicon)创建带有名称和图标的按钮例12-1

401、1建立窗体程序(LabelTest.java),输入一个正整数,判断该数是否是素数。界面设计如图所示。简单按钮(1)素数判断按钮actionPerformed事件代码如下:1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2/通过对话框输入数据3StringinputValue=JOptionPane.showInputDialog(请输入一个整数);4intr=Integer.valueOf(inputValue);/将字符串转换成整数5inti;6booleanflag=true;/当flag值为true,表

402、示是素数,否则不是素数。7/判断r是否被2.r/2的整数整除,如果有整除的,说明不是素数。8for(i=2;ir/2;i+)9if(r%i=0)flag=false;break;10if(flag)11jLabel1.setText(r+是素数);12else13jLabel1.setText(r+不是素数);14单选按钮2.单选按钮JRadioButton类实现了一个单选按钮,此按钮项可被选择或取消选择,并可为用户显示其状态。与ButtonGroup对象配合使用可创建一组按钮,一次只能选择其中的一个按钮。JRadioButton类的主要构造方法如下:JRadioButton(Iconicon

403、,booleanselected)创建一个具有指定图像和选择状态的单选按钮,但无文本。JRadioButton(Stringtext,Iconicon|,booleanselected)创建一个具有指定的文本、图像和选择状态的单选按钮。JRadioButton其它的主要方法有:isSelect(),表示是否选中了单选按钮。单选按钮ButtonGroup类是Object类的子类,它用于为一组按钮创建一个多斥(multiple-exclusion)作用域。使用相同的ButtonGroup对象创建一组按钮意味着“开启”其中一个按钮时,将关闭组中的其他所有按钮。一般情况下,可将ButtonGroup用

404、于任何从AbstractButton继承的对象组。例12-12创建一个JDialog窗体应用程序,进行食物喜好问题调查。请问喜欢吃蔬菜吗?请问喜欢吃肉类食物吗?界面设计如图所示。单选按钮1publicQuestionsDialog(java.awt.Frameparent,booleanmodal)2super(parent,modal);3initComponents();4buttonGroup1.add(jRadioButton1);5buttonGroup1.add(jRadioButton2);6buttonGroup1.add(jRadioButton3);71privatevoi

405、djButton1ActionPerformed(java.awt.event.ActionEventevt)2/得到面板jPanel2上的组件3Componentc1=jPanel2.getComponents();4inti;5Stringmsg1=;6JRadioButtonjrb;7for(i=0;ic1.length;i+)8/将Component对象转换成JRadioButton类型的对象9jrb=(JRadioButton)c1i;10if(jrb.isSelected()/如果选择了此单选按钮11msg1=jrb.getText();1213/得到面板jPanel3上的组件14

406、Componentc2=jPanel3.getComponents();15Stringmsg2=;16for(i=0;ic1.length;i+)17jrb=(JRadioButton)c2i;18if(jrb.isSelected()19msg2=jrb.getText();2021Stringmsg;22msg=你喜欢吃蔬菜吗?+你的回答是:+msg1;23msg=msg+,你喜欢吃蔬菜吗?+你的回答是:+msg2;24JOptionPane.showMessageDialog(null,msg);25复选框JCheckBox类的构造方法如下:JCheckBox(Stringtext,I

407、conicon|,booleanselected)创建一个带文本和图标的复选框,并指定其最初是否处于选定状态。JCheckBox类的主要方法有:isSelect(),表示是否选中了复选按钮。例12-13创建基于JFrame窗体程序(StudentInfo类),进行学生信息调查,主要调查男生、女生的爱好情况。界面设计如图所示。(1)StudentInfo类的构造方法如下:1publicStudentInfo()2initComponents();/系统产生3/向组按钮中添加两个JCheckBox按钮。4buttonGroup1.add(boy);5buttonGroup1.add(girl);6

408、(2)调查按钮的actionperformed事件方法代码如下:1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2Strings=;3inti;4booleanflag=false;/没有选择性别时,初始化falg标志。5/jPanel1.getComponentCount()方法返回面板jPanel1中的组件对象的个数6for(i=0;ijPanel1.getComponentCount();i+)7if(JRadioButton)jPanel1.getComponent(i).isSelected()8fl

409、ag=true;9s=性别是+(JRadioButton)jPanel1.getComponent(i).getText()+;101112if(!flag)/当没有选择性别时,flag=false;13JOptionPane.showMessageDialog(null,你没有选择性别,请重新选择!);14return;1516s=s+爱好有:;17for(i=0;ijPanel2.getComponentCount();i+)18if(JCheckBox)jPanel2.getComponent(i).isSelected()19s=s+(JCheckBox)jPanel2.getComp

410、onent(i).getText();2021jLabel2.setText(s);/将结果显示在标签jLabel2上。2212.4.5文本框文本框是一个文本编辑区域,还可以在开区域输入、修改和显示文本内容。在Swing中的文本框包括:简单文本框(JTextField)、输入密码框(JPassword)以及多行文本框(JTextArea)。简单文本框构造方法如下:JTextField(Documentdoc,Stringtext|,intcolumns)构造一个用指定文本和列初始化的新文本框。JTextField类的其它主要方法如下:intgetColumns()返回此TextField中的列

411、数。protectedintgetColumnWidth()返回列宽度。voidsetColumns(intcolumns)设置此TextField中的列数,然后验证布局。简单文本框例12-14创建基于JFrame类的窗体应用程序(),计算三角形的面积。简单文本框1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2doublea,b,c;3Stringmsg=;4if(jTextField1.getText().trim().length()=0)5msg=msg+边长边长a;6if(jTextField2.ge

412、tText().trim().length()=0)7msg=msg+,边长边长b;8if(jTextField3.getText().trim().length()=0)9msg=msg+,边长边长c;10jLabel4.setText(结果:结果:+msg);11if(msg.length()!=0)12msg=msg+,没有输入数据!,没有输入数据!;13jLabel4.setText(msg);14return;1516else17/得到三角形的三条边,分别保存在a,b,c18a=Double.valueOf(jTextField1.getText().trim();19b=Doubl

413、e.valueOf(jTextField2.getText().trim();20c=Double.valueOf(jTextField3.getText().trim();21/创建三角形对象22Triangle12t=newTriangle12(a,b,c);23try24doubles=t.getArea();/求得三角形的面积25jLabel4.setText(三角形的面积=+Double.toString(s);26catch(Exceptione)27jLabel4.setText(e.toString();282930输入密码框JPasswordField类的其它方法如下:boo

414、lean echoCharIsSet()如果此JPasswordField对象具有回显设置的字符,则返回true。chargetEchoChar()返回要用于回显的字符。chargetPassword()以字符数组形式返回此JPasswordField对象所输入的密码。voidsetEchoChar(charc)设置JPasswordField对象的回显字符。例12-15创建基于JFrame窗体程序(LoginSystem.java),界面设计如图所示。输入密码框1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)

415、2/得到输入的密码3Strings=newString(jPasswordField1.getPassword();4if(pareTo(abc123)=0)5JOptionPane.showMessageDialog(null,输入密码成功);6else7JOptionPane.showMessageDialog(null,输入密码不成功,请重新输入!);8多行文本框JTextArea类是一个显示纯文本的多行区域。JTextArea具有两个属性columns和rowsJTextArea类的主要方法如下:JTextArea(Documentdoc,Stringtext,introws,intc

416、olumns)构造具有指定行数和列数,给定文本、定模型的新的JTextArea。DimensiongetPreferredSize()返回TextArea的首选大小。protectedintgetRowHeight()定义行高的意义。intgetLineCount()确定文本区中所包含的行数。intgetRows()返回TextArea中的行数。voidsetRows(introws)设置此TextArea的行数。intgetColumns()返回TextArea中的列数。voidsetColumns(intcolumns)设置此TextArea中的列数。booleangetLineWrap(

417、)获取文本区的换行策略。voidsetLineWrap(booleanwrap)设置文本区的换行策略。booleangetWrapStyleWord()获取换行方式(如果文本区要换行)。voidsetWrapStyleWord(booleanword)设置换行方式(如果文本区要换行)voidappend(Stringstr)将给定文本追加到文档结尾。voidinsert(Stringstr,intpos)将指定文本插入指定位置。多行文本框举例例12-16编写个人信息录入程序(PostPersonInfo类), 数据输入完成后,提交显示所录入数据(PersonInfByPost类), 如图所示。

418、多行文本框举例(1)提交按钮的提交按钮的ActionPerformed事件处理程序代码如下:事件处理程序代码如下:1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)21if(sPassword.equals()22message.setText(密码不能为空!密码不能为空!);23password.requestFocus();/获得输入焦点。获得输入焦点。24return;2528PersonInfByPostt=newPersonInfByPost(this);29/将提交信息显示出来。将提交信息显示出来。3

419、0msg=学号学号:+sId;31t.append(msg);32msg=msg+姓名姓名:+sName;33t.append(msg);34msg=年龄年龄:+age.getText().trim();35t.append(msg);42this.setVisible(false);43t.setVisible(true);/显示提交信息显示提交信息44多行文本框举例(2)清除按钮的ActionPerformed事件处理程序代码如下:1privatevoidjButton2ActionPerformed(java.awt.event.ActionEventevt)2/TODOaddyourh

420、andlingcodehere:3studentId.setText();4studentName.setText();5age.setText();6password.setText();7information.setText();8多行文本框举例(3)创建了PersonInfByPost类,该类定义如下:publicclassPersonInfByPostextendsjavax.swing.JFramePostPersonInfopostPersonInfo;publicPersonInfByPost(PostPersonInfopi)postPersonInfo=pi;initCom

421、ponents();this.setSize(500,400);publicvoidappend(Strings)inf.append(s+n);privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)this.setVisible(false);postPersonInfo.setVisible(true);12.4.6列表和组合框列表框用来显示一个项目列表,用户可以选择其中一项或多项。如果项目比较多而又不能一次性全部显示出来的话,列表框会自动加上滚动条,用户可以通过拉动滚动条查看所有项目。组合框是合并了文本框和列表而

422、形成的一种控件。组合框可以像文本框那样接收用户的输入信息,还能够像列表框一样列出多个项目供用户选择。Swing中的列表框是JList,组合框是JComboBox。列表框(1)“报纸样式”布局,单元按先纵向后横向流动(2)“报纸样式”,但单元按先横向后纵向流动(3)指示默认布局:一列单元.JList有三种布局方式有三种布局方式列表框JList类的主要方法如下:类的主要方法如下:JList()构造一个使用空模型的构造一个使用空模型的JList。JList(ListModeldataModel)构造一个构造一个JList对象,其使用指定的对象,其使用指定的ListModel对象显示元素。对象显示元素

423、。JList(ObjectlistData)构造一个构造一个JList,使其显示指定数组中的元素。,使其显示指定数组中的元素。JList(VectorlistData)构造一个构造一个JList,使其显示指定,使其显示指定Vector中的元素。中的元素。voidclearSelection()清除选择,调用此方法后,清除选择,调用此方法后,isSelectionEmpty将返回将返回true。protectedListSelectionModelcreateSelectionModel()返回返回DefaultListSelectionModel实例。实例。ListModelgetModel(

424、)返回保存由返回保存由JList组件显示的项列表的数据模型。组件显示的项列表的数据模型。voidsetModel(ListModelmodel)设置表示列表内容或设置表示列表内容或“值值”的模型,并在通知的模型,并在通知PropertyChangeListener之后清除列表选择。之后清除列表选择。intgetSelectedIndex()返回所选的第一个索引;如果没有选择项,则返回返回所选的第一个索引;如果没有选择项,则返回-1。voidsetSelectedIndex(intindex)选择单个单元。选择单个单元。intgetSelectedIndices()返回所选的全部索引的数组(按升

425、序排列)。返回所选的全部索引的数组(按升序排列)。voidsetSelectedIndices(intindices)选择一组单元。选择一组单元。列表框ObjectgetSelectedValue()返回所选的第一个值,如果选择为空,则返回返回所选的第一个值,如果选择为空,则返回null。Object getSelectedValues()返回所选单元的一组值。返回所选单元的一组值。intgetSelectionMode()返回允许单项选择还是多项选择。返回允许单项选择还是多项选择。ListSelectionModelgetSelectionModel()返回当前选择模型的值。返回当前选择模型

426、的值。voidsetSelectionModel(ListSelectionModelselectionModel)将列表的将列表的selectionModel设置为非设置为非null的的ListSelectionModel实现。实现。intgetVisibleRowCount()返回首选可见行数。返回首选可见行数。voidsetVisibleRowCount(intvisibleRowCount)设置不使用滚动条可以在列表中显示的设置不使用滚动条可以在列表中显示的首选行数,这一点由最近的首选行数,这一点由最近的JViewport祖先(如果有)确定。祖先(如果有)确定。boolean isSe

427、lectedIndex(intindex)如果选择了指定的索引,则返回如果选择了指定的索引,则返回true。boolean isSelectionEmpty()如果什么也没有选择,则返回如果什么也没有选择,则返回true。voidsetListData(ObjectlistData)根据一个根据一个object数组构造数组构造ListModel,然后对其应用,然后对其应用setModel。voidsetListData(VectorlistData)根据根据Vector构造构造ListModel,然后对其应用,然后对其应用setModel。voidsetSelectionMode(intsel

428、ectionMode)确定允许单项选择还是多项选择。确定允许单项选择还是多项选择。列表框JList还需和列表接口ListModel、类DefaultListModel结合一起来使用。其中接口ListModel用于用于获取列表中每个项目的值以及列表的长度;而类DefaultListModel则以松散方式实现java.util.Vector的API。列表框更新JList的项列表的方法有:(1)使用Vector,编程者可以将数据项都存放在Vector对象中,然后调用JList类的setListData()方法。 (2)通过构造函数添加数据。(3)通过DefaultListModel对象添加需要的数据

429、,然后调用JList类的setModel()方法。例12-17创建窗体应用程序(SelectCourse类),其界面如图所示。列表框(1)SelectCourse类的构造方法如下:publicSelectCourse(java.awt.Frameparent,booleanmodal)super(parent,modal);initComponents();/设置列表框jList1的项目值Stringdata=大学英语,大学物理,计算机基础,C语言程序设计,Java程序设计,VB程序设计,VF程序设计;jList1.setListData(data);列表框(2)添加按钮的actionPerf

430、ormed事件处理程序代码如下:1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2/TODOaddyourhandlingcodehere:3ListModellm1;/4/利用DefaultListModel类的对象保存jList2的项目列表5DefaultListModellm2=newDefaultListModel();6inti;7/保持列表框jList2的原来数据8lm1=jList2.getModel();9for(i=0;ilm1.getSize();i+)10lm2.addElement(lm

431、1.getElementAt(i);11inta=jList1.getSelectedIndices();12/得到列表框jList1的ListModel接口的对象13lm1=jList1.getModel();14booleanflag1=false;/flag1表示选择加入的课程是否存在于已选课课程中。15booleanflag2=false;/flag2表示所有选择加入的课程是否不存在于已选课课程中,16Stringmsg=;17/检查从列表框jList1中所选的数据是否存在于列表框jList2中,如果存在则,先加入到18for(i=0;ia.length;i+)19Stringt=(S

432、tring)lm1.getElementAt(ai);20/查找t是否在DefaultListModel类的对象lm2中,如果不在列表框21if(!isContainValue(lm2,t)22flag2=true;/23lm2.addElement(String)t);/则加入到lm2中2425else26/msg保存已经存在于选择的课程名。27if(pareTo()=0)28msg=t;29else30msg=msg+,+t;31flag1=true;323334if(flag2)/更新数据35jList2.setModel(ListModel)lm2);36msg=当前你选择的课程(+m

433、sg+),您已经选了。;37if(flag1)/显示已经存在的课程名称。38JOptionPane.showMessageDialog(null,msg);3940privatevoidjButton3ActionPerformed(java.awt.event.ActionEventevt)41/TODOaddyourhandlingcodehere:42Vectorv=newVector();/通过Vector初始化列表框jList2的列表项43jList2.setListData(v);44组合框组合框是文本框和列表框的组合,Swing中的JComboBox就是组合框。JComboBox

434、类的主要方法如下:JComboBox()创建具有默认数据模型的JComboBox对象。JComboBox(ComboBoxModelcbModel)创建一个JComboBox对象,其项取自现有的ComboBoxModel中。JComboBox(Objectitems)创建包含指定数组items中的元素的JComboBox。ObjectgetItemAt(intindex)返回指定索引处的列表项。intgetItemCount()返回列表中的项数。intgetMaximumRowCount()返回组合框不使用滚动条可以显示的最大项数intgetSelectedIndex()返回列表中与给定项匹配

435、的第一个选项。ObjectgetSelectedItem()返回当前所选项。ObjectgetSelectedObjects()返回包含所选项的数组。voidinsertItemAt(ObjectanObject,intindex)在项列表中的给定索引处插入项。voidremoveAllItems()从项列表中移除所有项。voidremoveItem(Objectobject)从项列表中移除项。voidremoveItemAt(intpos)移除pos处的项。voidsetEditable(booleanflag)确定JComboBox字段是否可编辑。voidsetModel(ComboBox

436、Modelm)设置JComboBox用于获取项列表的数据模型。voidsetSelectedIndex(intindex)选择索引index处的项。voidsetSelectedItem(Objectobject)将组合框显示区域中所选项设置为参数中的对象。组合框举例例12-18创建设置字体应用程序(SetFont类),如图所示,设计文本框的字体,字大小以及颜色。组合框举例(1)SetFont类的构造方法如下:1publicSetFont(java.awt.Frameparent,booleanmodal)2super(parent,modal);3initComponents();4/得到本

437、地图形环境5GraphicsEnvironmentge=GraphicsEnvironment.getLocalGraphicsEnvironment();6Stringfonts=ge.getAvailableFontFamilyNames();7/设置字体组合框8for(Stringfont:fonts)9jComboBox1.addItem(font);1011inti;12/设置字体大小组合框13for(i=0;i100;i+)14jComboBox2.addItem(String.valueOf(i);15/设置颜色组合框16Stringcolors=黑色,蓝色,青色,深灰色,灰色,

438、绿色,洋红色,粉红色,黄色;17for(i=0;icolors.length;i+)18jComboBox3.addItem(colorsi);19组合框举例(2)确定按钮的ActionPerformed事件处理程序代码如下:1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2/TODOaddyourhandlingcodehere:3/得到所选择字体名称4StringfontName=(String)jComboBox1.getSelectedItem();5/得到字体大小6StringsizeStr=(Str

439、ing)jComboBox2.getSelectedItem();7intfontSize=Integer.parseInt(sizeStr);8/得到所选择颜色9Colorcolor=selectColor(String)jComboBox3.getSelectedItem();10/设置文本框的字体,字体大小,颜色11Fontfont=newFont(fontName,Font.TRUETYPE_FONT,fontSize);12jTextField1.setFont(font);/设置字体13jTextField1.setForeground(color);/改变前景颜色14滑块滑块控件

440、是让用户以图形方式在有界区间内通过移动滑块来选择值的组件。滑块可以显示主刻度标记和次刻度标记。Swing中定义了JSlider类是滑块。JSlider类的主要方法如下:类的主要方法如下:JSlider(intorientation,intmin,intmax,intvalue)用指定的方向和指定的最小值、最大用指定的方向和指定的最小值、最大值以及初始值创建一个滑块。值以及初始值创建一个滑块。intgetExtent()返回滑块所返回滑块所“覆盖覆盖”的值的范围。的值的范围。booleangetInverted()如果滑块显示的值范围反转,则返回如果滑块显示的值范围反转,则返回true。intg

441、etMajorTickSpacing()此方法返回主刻度标记的间隔。此方法返回主刻度标记的间隔。intgetMinorTickSpacing()此方法返回次刻度标记的间隔。此方法返回次刻度标记的间隔。voidsetMinorTickSpacing(intn)此方法设置次刻度标记的间隔。此方法设置次刻度标记的间隔。intgetMaximum()返回滑块所支持的最大值。返回滑块所支持的最大值。intgetMinimum()返回此滑块所支持的最小值。返回此滑块所支持的最小值。intgetOrientation()返回此滑块的垂直或者水平方向。返回此滑块的垂直或者水平方向。voidsetMajorTi

442、ckSpacing(intn)此方法设置主刻度标记的间隔。此方法设置主刻度标记的间隔。voidsetMaximum(intmaximum)设置模型的最大值属性。设置模型的最大值属性。voidsetMinimum(intminimum)设置模型最小值属性。设置模型最小值属性。voidsetOrientation(intorientation)将滚动条的方向设置为将滚动条的方向设置为VERTICAL或者或者HORIZONTAL。voidsetValue(intn)设置滑块的当前值。设置滑块的当前值。滑块举例例12-19创建设计字体应用程序(SetFont2类)。如图所示。滑块举例1、jSlider

443、1对象的StateChanged事件处理程序如下:1privatevoidjSlider1StateChanged(javax.swing.event.ChangeEventevt)2/TODOaddyourhandlingcodehere:3Fontf=jTextField1.getFont();/得到文本框的原来字体4/创建新字体,仅利用滑块的值来改变文本框字体的大小5f=newFont(f.getFontName(),f.getStyle(),jSlider1.getValue();6jTextField1.setFont(f);/72、退出按钮的ActionPerformed事件处理程

444、序如下:1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2System.exit(0);/退出程序312.4.8微调器微调器通常提供一对带小箭头的按钮以便逐步遍历序列元素。键盘的向上/向下方向键也可循环遍历元素。也允许用户在微调器中直接输入合法值。Swing中定义的JSpinner是微调器。JSpinner类的主要方法如下:JSpinner()构造一个spinner,使其具有初始值为0并且无任何最小值或者最大值限制。JSpinner(SpinnerModelm)构造具有一对next/previous按钮和Spi

445、nnerModel编辑器的完整微调器。voidcommitEdit()将当前编辑的值提交给SpinnerModel。JComponentgetEditor()返回显示和潜在更改模型值的组件。voidsetEditor(JComponenteditor)更改显示SpinnerModel当前值的JComponent。SpinnerModelgetModel()返回定义此spinner值序列的SpinnerModel。voidsetModel(SpinnerModelmodel)更改表示此spinner值的模型。ObjectgetPreviousValue()返回序列中由getValue()所返回对

446、象之前的对象。ObjectgetNextValue()返回序列中由getValue()所返回的对象之后的对象。ObjectgetValue()返回模型的当前值,通常该值是editor所显示的值。voidsetValue(Objectvalue)更改模型的当前值,通常此值是editor所显示的值。微调器JSpinner类中提供了四个内部嵌套,用以规定输入不同的数据。这四个内部嵌套分别是:(1)JSpinner.DateEditor其模型为SpinnerDateModel的JSpinner编辑器。(2)JSpinner.DefaultEditor该类在FormattedTextField中显示模型

447、当前值的只读视图。(3)JSpinner.ListEditor其模型为SpinnerListModel的JSpinner编辑器。(4)JSpinner.NumberEditor其模型为SpinnerNumberModel的JSpinner编辑器。例12-20创建设计字体程序(SetFont3.java),如图所示。微调器举例publicclassSetFont3extendsjavax.swing.JDialog/设置微调器的微调数值模型SpinnerNumberModelsnm=newSpinnerNumberModel(fontSize,1,100,2);jSpinner1.setMode

448、l(snm);/微调器的编辑器中只许可输入数值 JSpinner.NumberEditoreditor=newJSpinner.NumberEditor(jSpinner1,0);jSpinner1.setEditor(editor);/设定微调器的编辑器jSpinner1.setValue(newInteger(fontSize);/设置微调器的初始值./微调器jSpinner的StateChanged事件处理代码privatevoidjSpinner1StateChanged(javax.swing.event.ChangeEventevt)Fontf=jTextField1.getFon

449、t();/得到文本框的原来字体/创建新字体,仅利用微调器的值来改变文本框字体的大小fontSize=(Integer)jSpinner1.getValue();f=newFont(f.getFontName(),f.getStyle(),fontSize);jTextField1.setFont(f);/退出按钮的事件处理程序代码privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)System.exit(0);12.4.8进度条进度条通常通过显示某个操作的完成百分比。JProgressBar类的主要方法如下:JPro

450、gressBar(BoundedRangeModelmodel)创建使用指定的保存进度条数据模型的水平进度条。JProgressBar(intorient,intmin,intmax)创建使用指定方向(JProgressBar.VERTICAL或JProgressBar.HORIZONTAL)、最小值和最大值的进度条。intgetMaximum()返回进度条的最大值。intgetMinimum()返回进度条的最小值。doublegetPercentComplete()返回进度条的完成百分比。StringgetString()返回进度字符串的当前值。intgetValue()返回进度条的当前值,

451、该值存储在进度条的BoundedRangeModel中。voidsetMaximum(intn)将进度条的最大值(存储在进度条的数据模型中)设置为n。voidsetMinimum(intn)将进度条的最小值(存储在进度条的数据模型中)设置为n。voidsetOrientation(intnewOrientation)将进度条的方向设置为newOrientation(必须为JProgressBar.VERTICAL或JProgressBar.HORIZONTAL)。voidsetString(Strings)设置进度字符串的值。 voidsetValue(intn)将进度条的当前值(存储在进度条

452、的数据模型中)设置为n。进度条举例例12-21创建窗体应用程序ProgressBarFrame,如图所示,在窗体上添加一个进度条,当点击开始按钮时,显示当前已经完成进度。进度条举例(1)首先,创建自定义线程MyProgressBarThread类,其代码情况如下:1publicclassMyProgressBarThreadextendsThread2JProgressBarjp;/进度条3publicMyProgressBarThread(JProgressBarjp)4this.jp=jp;56Override7publicvoidrun()8inti;9intvalue;10jp.set

453、StringPainted(true);11for(i=1;i=jp.getMaximum();i+)12jp.setValue(i);/设置进度条的当前值13jp.setString(当前已经完成+i+%.);14try15Thread.currentThread().sleep(200);/毫秒1617catch(Exceptione);1819jp.setString(全部完成);2021进度条举例(2)开始按钮的事件处理程序的代码情况如下:1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2/初始化进度条

454、3jProgressBar1.setValue(0);/设置初始值4jProgressBar1.setMaximum(100);/设置进度条的最大值5/创建自定义线程6MyProgressBarThreadmyThread=newMyProgressBarThread(jProgressBar1);7jButton1.setEnabled(false);/让按钮变灰无效8myThread.start();/启动线程9jButton1.setEnabled(false);/让按钮有效10返回目录12.5菜单组件Swing菜单组件由菜单栏(JMenuBar)、菜单(JMenu)、菜单项(JMenu

455、Item)、弹出菜单(JPopupMenu)。 一个菜单栏由若干个菜单组成,一个菜单又由若干个菜单项组成。一般菜单栏放JFrame窗口、JDialog窗口中,只要调用 JFrame类的setMenuBar()方法即可。菜单栏JMenuBar菜单栏JMenuBar的主要方法如下:JMenuBar()创建新的菜单栏。JMenuadd(JMenuc)将指定的菜单追加到菜单栏的末尾。intgetComponentIndex(Componentc)返回指定组件的索引。JMenugetMenu(intindex)返回菜单栏中指定位置的菜单。intgetMenuCount()返回菜单栏上的菜单数。boole

456、an isSelected()如果当前已选择了菜单栏的组件,则返回true。voidsetSelected(Componentsel)设置当前选择的组件,更改选择模型。菜单JMenu菜单JMenu的主要方法如下:JMenu(Actiona)构造一个从提供的Action获取其属性的菜单。JMenu(Strings,booleanb)构造一个新JMenu,用提供的字符串作为其文本并指定其是否为分离式菜单。JMenuItemadd(Xa)创建连接到指定X对象的新菜单项,并将其追加到此菜单的末尾,其中X可以是Action、JMenuItem、Component、String等类的对象。voidaddS

457、eparator()将新分隔符追加到菜单的末尾。intgetDelay()返回子菜单向上或向下弹出前建议的延迟(以毫秒为单位)。JMenuItemgetItem(intpos)返回指定位置的JMenuItem。intgetItemCount()返回菜单上的项数,包括分隔符。ComponentgetMenuComponent(intn)返回位于n的组件。intgetMenuComponentCount()返回菜单上的组件数。ComponentgetMenuComponents()返回菜单子组件的Component数组。JPopupMenugetPopupMenu()返回与此菜单关联的弹出菜单。M

458、enuElementgetSubElements()返回由MenuElement组成的数组,其中包含此菜单组件的子菜单。菜单JMenuvoidinsert(Strings,intpos)在给定的位置插入一个具有指定文本的新菜单项。JMenuIteminsert(Actiona,intpos)在给定位置插入连接到指定Action对象的新菜单项。JMenuIteminsert(JMenuItemmi,intpos)在给定位置插入指定的菜单项。voidinsertSeparator(intindex)在指定的位置插入分隔符。boolean isSelected()如果菜单是当前选择的(即突出显示的)

459、菜单,则返回true。voidremove(JMenuItemitem)从此菜单移除指定的菜单项。voidremove(intpos)从此菜单移除指定索引处的菜单项。voidremove(Componentc)从此菜单移除组件c。voidremoveAll()从此菜单移除所有菜单项。voidsetModel(ButtonModelnewModel)设置“菜单按钮”的数据模型,即用户单击可以打开或关闭菜单的标签。voidsetPopupMenuVisible(booleanb)设置菜单弹出的可见性。voidsetSelected(booleanb)设置菜单的选择状态。菜单项JMenuItem(3

460、)菜单项JMenuItem菜单项本质上是位于列表中的按钮。当用户选择“按钮”时,将执行与菜单项关联的操作。JPopupMenu中包含的JMenuItem也是执行该操作。KeyStrokegetAccelerator()返回作为菜单项的加速器的KeyStroke。MenuElementgetSubElements()此方法返回包含此菜单组件的子菜单组件的数组。ComponentgetComponent()返回用于绘制此对象的java.awt.Component。voidsetEnabled(booleanb)启用或禁用菜单项。voidsetAccelerator(KeyStrokekeyStro

461、ke)设置组合键,它能直接调用菜单项的操作侦听器而不必显示菜单的层次结构。弹出菜单JPopupMenu(4)弹出菜单JPopupMenuJPopupMenu类的主要方法如下:JPopupMenu()构造一个不带“调用者”的JPopupMenu。JPopupMenu(Stringlabel)构造一个具有指定标题的JPopupMenu。JMenuItemadd(Xa)创建连接到指定X对象的新菜单项,并将其追加到此菜单的末尾,其中X可以是Action、JMenuItem、Component、String等类的对象。voidaddSeparator()将新分隔符追加到菜单的末尾。protectedJM

462、enuItemcreateActionComponent(Actiona)该工厂方法为添加到JPopupMenu的Action创建对应的JMenuItem。StringgetLabel()返回弹出菜单的标签。SingleSelectionModelgetSelectionModel()返回处理单个选择的模型对象。MenuElementgetSubElements()返回MenuElement组成的数组,包含此菜单组件的子菜单。voidinsert(Actiona,intindex)在给定位置插入对应于指定Action对象的菜单项。voidinsert(Componentcomponent,in

463、tindex)将指定组件插入到菜单的给定位置。voidremove(intpos)从此弹出菜单移除指定索引处的组件。voidsetLabel(Stringlabel)设置弹出菜单的标签。voidsetSelected(Componentsel)设置当前选择的组件,此方法将更改选择模型。voidsetSelectionModel(SingleSelectionModelmodel)设置处理单个选择的模型对象例12-22创建如图所示应用程序。(1)MenuJFrame类的主要属性如下代码:1publicclassMenuJFrameextendsjavax.swing.JFrame2intstar

464、tx,starty,endx,endy;/画图形的起始坐标与终点坐标3inttype;/图形类别,1是矩形,2是椭圆4intcolors;/图形颜色,1是红色,2是蓝色5JPopupMenujpm;6.7(2)MenuJFrame类的构造方法代码如下:1publicMenuJFrame()2initComponents();3type=1;/开始画圆。4colors=1;/开始用红色画图5/创建弹出菜单6jpm=newJPopupMenu(选择功能);7/为弹出菜单添加菜单项8jpm.add(red1);9jpm.add(blue1);10jpm.addSeparator();11jpm.ad

465、d(rectangle1);12jpm.add(circle1);13this.setJMenuBar(jMenuBar1);/设置窗体菜单14(3)自定义了画图方法,其代码如下:1privatevoiddraw()2/得到面板jPanel1的图形环境3Graphicsg=jPanel1.getGraphics();4switch(colors)5case1:/6/将图形设置为红色7g.setColor(Color.red);8break;9case2:/将图形设置为蓝色10g.setColor(Color.blue);1112switch(type)13case1:14/画矩形15g.dra

466、wRect(startx,starty,Math.abs(startx-endx),Math.abs(starty-endy);16break;17case2:18/画圆或椭圆19g.drawOval(startx,starty,Math.abs(startx-endx),Math.abs(starty-endy);2021(4)菜单栏的矩形菜单项的ActionPerformed事件处理程序,其代码如下:privatevoidrectangleActionPerformed(java.awt.event.ActionEventevt)type=1;/图形类别,1是矩形,2是椭圆(5)菜单栏的退

467、出菜单项的ActionPerformed事件处理程序,其代码如下:privatevoidquitActionPerformed(java.awt.event.ActionEventevt)System.exit(0);(6)颜色菜单项的ActionPerformed事件处理程序,其代码如下:privatevoidredActionPerformed(java.awt.event.ActionEventevt)colors=1;/(7)面板对象jPanel1按下鼠标的事件处理程序,其代码如下:1privatevoidjPanel1MousePressed(java.awt.event.Mouse

468、Eventevt)2/单击鼠标左键时才可以画图形3if(evt.getButton()=MouseEvent.BUTTON1)4startx=evt.getX();5starty=evt.getY();67(8)面板对象jPanel1松开鼠标的事件处理程序,其代码如下:1privatevoidjPanel1MouseReleased(java.awt.event.MouseEventevt)2/松开鼠标左键时3if(evt.getButton()=MouseEvent.BUTTON1)4endx=evt.getX();5endy=evt.getY();6draw();78(9)面板对象jPan

469、el1单击鼠标的事件处理程序,其代码如下:1privatevoidjPanel1MouseClicked(java.awt.event.MouseEventevt)2/返回按的是那个键3switch(evt.getButton()4/按下左键5caseMouseEvent.BUTTON1:break;6/按下中间键7caseMouseEvent.BUTTON2:break;8/按下右键9caseMouseEvent.BUTTON3:10intx1=jPanel1.getX();11inty1=jPanel1.getY();12/此处evt.getComponent()是返回右单击事件的发起者1

470、3jpm.show(evt.getComponent(),evt.getPoint().x,evt.getPoint().y);1415返回目录12.6工具栏JToolBar的构造方法如下:的构造方法如下:JToolBar()创建新的工具栏;默认的方向为HORIZONTAL。JToolBar(intorientation)创建具有指定orientation的新工具栏。JToolBar(Stringname)创建一个具有指定name的新工具栏。JToolBar(Stringname,intorientation)创建一个具有指定name和orientation的新工具栏。JToolBar类的其它

471、主要方法有:类的其它主要方法有:JButtonadd(Actiona)添加一个指派操作的新的JButton。voidaddSeparator()将默认大小的分隔符追加到工具栏的末尾。voidaddSeparator(Dimensionsize)将指定大小的分隔符追加到工具栏的末尾。protectedJButton createActionComponent(Actiona)将为Action创建JButton的工厂方法添加到JToolBar中。ComponentgetComponentAtIndex(inti)返回指定索引位置的组件。intgetComponentIndex(Componentc

472、)返回指定组件的索引。工具栏intgetOrientation()返回工具栏的当前方向。boolean isFloatable()获取floatable属性。boolean isRollover()返回rollover状态。voidsetFloatable(booleanb)设置floatable属性,如果要移动工具栏,此属性必须设置为true。voidsetLayout(LayoutManagermgr)设置此容器的布局管理器。voidsetOrientation(into)设置工具栏的方向。Action和AbstractActionAction接口提供ActionListener接口的一个

473、有用扩展,以便若干控件访问相同的功能。AbstractAction抽象类提供JFCAction接口的默认实现。AbstractAction抽象类的主要方法如下:protectedObjectclone()克隆抽象操作。Object getKeys()返回Object的数组,这些对象是一些已经为其设置此AbstractAction值的键,如果没有已经设置该值的键,则返回null。ObjectgetValue(Stringkey)获得与指定键关联的Object。voidputValue(Stringkey,ObjectnewValue)设置与指定键关联的Value。boolean isEnable

474、d()如果启用该操作,则返回true。voidsetEnabled(booleannewValue)启用或禁用该操作。工具栏举例例例12-23 在例在例12-22的基的基础上,增加两个工具上,增加两个工具栏(颜色工色工具具栏、图形形类型型工具工具栏),同),同时在其它菜在其它菜单列中增加两列中增加两个菜个菜单项(查看看颜色工具色工具栏、查看看图形工具形工具栏),如,如图所所示。示。工具栏举例先定义AbstractAction类的派生类:ActionOfBlueColor、ActionOfRedColor、ActionOfRectangle以及ActionOfCircle。(1)在ActionO

475、fBlueColor.java文件中定义ActionOfBlueColor类,其代码如下:1publicclassActionOfBlueColorextendsAbstractAction2/添加窗体框架对象jf,目的是:在actionPerformed(.)中访问jf对象中的方法。3ActionJFramejf;4publicActionOfBlueColor(ActionJFramejf,Stringtext,ImageIconicon,5Stringdesc,Integermnemonic)6super(text,icon);/设置父类的属性7this.jf=jf;8putValue(

476、SHORT_DESCRIPTION,desc);/对象具体说明9putValue(MNEMONIC_KEY,mnemonic);/设置记忆键1011/设置蓝色12publicvoidactionPerformed(ActionEvente)13jf.setColors(2);1415工具栏举例(2)定义ActionOfRedColor类,其代码如下:1publicclassActionOfRedColorextendsAbstractAction2/添加窗体框架对象jf,目的是:在actionPerformed(.)中访问jf对象中的方法。3ActionJFramejf;4publicActi

477、onOfRedColor(ActionJFramejf,Stringtext,ImageIconicon,5Stringdesc,Integermnemonic)6super(text,icon);7this.jf=jf;8putValue(SHORT_DESCRIPTION,desc);9putValue(MNEMONIC_KEY,mnemonic);1011publicvoidactionPerformed(ActionEvente)12jf.setColors(1);1314工具栏举例(3)定义ActionOfRectangle类,其代码如下:1publicclassActionOfRe

478、ctangleextendsAbstractAction2/添加窗体框架对象jf,目的是:在actionPerformed(.)中访问jf对象中的方法。3ActionJFramejf;4publicActionOfRectangle(ActionJFramejf,Stringtext,ImageIconicon,5Stringdesc,Integermnemonic)6super(text,icon);7this.jf=jf;8putValue(SHORT_DESCRIPTION,desc);9putValue(MNEMONIC_KEY,mnemonic);1011/设置矩形12publicv

479、oidactionPerformed(ActionEvente)13jf.setType(1);1415工具栏举例(4)定义ActionOfCircle类,其代码如下:1publicclassActionOfCircleextendsAbstractAction2/添加窗体框架对象jf,目的是:在actionPerformed(.)中访问jf对象中的方法。3ActionJFramejf;4publicActionOfCircle(ActionJFramejf,Stringtext,ImageIconicon,5Stringdesc,Integermnemonic)6super(text,ico

480、n);7this.jf=jf;8putValue(SHORT_DESCRIPTION,desc);9putValue(MNEMONIC_KEY,mnemonic);1011/设置画圆形或椭圆12publicvoidactionPerformed(ActionEvente)13jf.setType(2);1415工具栏举例(5)定义ActionJFrame类,其代码如下:publicclassActionJFrameextendsjavax.swing.JFrameintstartx,starty,endx,endy;/画图形的起始坐标与终点坐标inttype;/图形类别,1是矩形,2是椭圆in

481、tcolors;/图形颜色,1是红色,2是蓝色JPopupMenujpm;/弹出菜单protectedActionactionOfBlueColor,actionOfRedColor,actionOfRectangle,actionOfCircle;.publicActionJFrame()initComponents();/默认画图type=1;/开始画圆。colors=1;/开始用红色画图actionOfBlueColor=newActionOfBlueColor(this,蓝色B,null,图形线条颜色是蓝色,newInteger(KeyEvent.VK_B);.Actionaction

482、1=actionOfBlueColor,actionOfRedColor;Actionaction2=actionOfRectangle,actionOfCircle;JMenuItemmenuItem;inti;工具栏举例/在color菜单下添加菜单项for(i=0;iaction1.length;i+)menuItem=newJMenuItem(action1i);color.add(menuItem);/在shape菜单下添加菜单项for(i=0;iaction1.length;i+)menuItem=newJMenuItem(action2i);shape.add(menuItem);

483、this.setJMenuBar(jMenuBar1);/设置窗体菜单/创建弹出菜单jpm=newJPopupMenu(选择功能);/为弹出菜单添加菜单项for(i=0;iaction1.length;i+)menuItem=newJMenuItem(action1i);jpm.add(menuItem);/添加分隔线jpm.addSeparator();for(i=0;iaction1.length;i+)menuItem=newJMenuItem(action2i);jpm.add(menuItem);JButtonjb;/为颜色工具栏添加菜单项for(i=0;iaction1.lengt

484、h;i+)jb=newJButton(action1i);jToolBar1.add(jb);/为图形工具栏添加菜单项for(i=0;i0)/如果目标表结构跟源表结构不同如果目标表结构跟源表结构不同10if(!isSameStructure(dtm1,dtm2)11/得到原表结构和空数据的表格得到原表结构和空数据的表格12dtm2=getDefaultTableModel(dtm1);13/设置设置jTable2的数据模型的数据模型14jTable2.setModel(dtm2);1516else17System.out.println(表结构相同表结构相同);18/得到所选数据的索引号,保存

485、在数组中。得到所选数据的索引号,保存在数组中。19inta=jTable1.getSelectedRows();20/定义数组存储一行记录定义数组存储一行记录21Objectrecord=newObjectdtm1.getColumnCount();表格举例22inti,k,j;23for(k=0;ka.length;k+)24intp=ak;25for(i=0;i=0)32recordi=(Object)dtm1.getValueAt(p,j);33else34recordi=-;3536/将记录加入到表将记录加入到表jTable2中。中。37dtm2.addRow(record);3839

486、40表格举例(3)删除按钮的事件处理程序代码如下:删除按钮的事件处理程序代码如下:1privatevoidjButton2ActionPerformed(java.awt.event.ActionEventevt)2/TODOaddyourhandlingcodehere:3/得到表格得到表格jTable2的数据模型的数据模型4DefaultTableModeldtm2=(DefaultTableModel)jTable2.getModel();5/得到所选数据的行数得到所选数据的行数6intnumOfRow=jTable2.getSelectedRows().length;7for(inti

487、=0;i0)1314intch=in.read();/从输入流中读字符,并返回该字符15out.write(ch);/将字符ch写入到输出流out中1617in.close();/关闭输入流18out.close();/关闭输出流19catch(FileNotFoundExceptione)20System.out.println(错误,该文件不打开);21catch(IOExceptione)22System.out.println(文件不能读写!);23242513.2.2过滤数据流为了解决不同数据流之间速度、数据格式差异的矛盾,以便提高输入/输出操作的效率,特别是当需要大量输入/输出操作

488、的程序,Java为此提供了过滤流。过滤流主要包括:缓冲区数据流、数据数据流、管道数据流、对象数据流等。过滤流主要包括:缓冲区数据流、数据数据流、管道数据流、对象数据流等。过滤数据流BufferedOutputStream类的构造方法如下:BufferedOutputStream(OutputStreamoutputStream,ints)创建一个缓冲输出流,以将指定缓冲区大小的数据写入指定的输出流。如果没有指定缓冲区大小,则使用默认缓冲区大小是1024字节。与OutputStream类相比,BufferedOutputStream类中增加了如下方法:voidflush()刷新此缓冲的输出流。过

489、滤数据流过滤数据流举例例13-4创建Java源程序CopyFile2.java,重新实现例13-3的功能,复制当前工作目录下的file1.txt到当前工作目录下的file3.txt中。1publicclassCopyFile22publicstaticvoidmain(Strings)3/得到用户的当前工作目录4StringcurPath=System.getProperty(user.dir);5try6FileInputStreamin=newFileInputStream(curPath+/file1.txt);7FileOutputStreamout=newFileOutputStre

490、am(curPath+/file3.txt);8/创建缓冲输入流对象,并设置其缓冲区大小为1024字节。9BufferedInputStreaminBuf=newBufferedInputStream(in,1024);10/创建缓冲输出流对象,并设置其缓冲区大小为1024字节。11BufferedOutputStreamoutBuf=newBufferedOutputStream(out,1024);12intlen=0;13byteb=newbyte1024;14while(inBuf.available()0)1516len=inBuf.read(b);/记录下每次从缓冲输入流中的有效数

491、据长度17outBuf.write(b);/仅仅将数组b中的有效数据写出到输出流中。1819outBuf.flush();/刷新缓冲的输出流。20out.close();/关闭输出流21inBuf.close();/关闭输入缓冲流22in.close();2313.2.3数据输入/输出流数据输入流类DataInputStream允许应用程序以与机器无关方式从指定输入流中读取基本Java数据类型。DataInputStream(InputStreamin)使用指定DataInputStream创建一个DataInputStream。boolean readBoolean()读取一个输入字节,如果

492、该字节不是零,则返回true,如果是零,则返回false。xyreadXy()读取一个输入的xy并返回该xy值,其中Xy是Boolean、Byte、Char、Double、Long、Short、Int以及Float,而xy则可以是boolean、byte、char、double、long、short、int以及float。voidreadFully(byteb)从输入流中读取一些字节,并将它们存储到缓冲区数组b中。voidreadFully(byteb,intoff,intlen)从输入流中读取len个字节。intreadUnsignedByte()读取一个输入字节,将它左侧补零转变为int类

493、型,并返回结果,所以结果的范围是0到255。intreadUnsignedShort()读取两个输入字节,并返回0到65535范围内的一个int值。StringreadUTF()读入一个已使用UTF-8修改版格式编码的字符串。intskipBytes(intn)试图在输入流中跳过数据的n个字节,并丢弃跳过的字节。数据输入/输出流2.DataOutputStreamDataOutputStream允许应用程序以适当方式将基本Java数据类型的数据写入输出流中。以后,应用程序可以使用数据输入流将数据读入。DataOutputStream的主要方法如下:DataOutputStream(Output

494、Streamout)创建一个新的数据输出流,将数据写入指定输出流out。voidflush()清空此数据输出流。intsize()返回计数器written的当前值,即到目前为止写入此数据输出流的字节数。voidwrite(byteb,intoff,intlen)将指定字节数组中从偏移量off开始的len个字节写入输出流。voidwriteXy()将一个xy值写入输出流,其中Xy分别是Byte、Char、Double、Long、Short、Int以及Float,而xy分别是byte、char、double、long、short、int以及float。voidwriteChars(Strings)

495、将字符串按字符顺序写入输出流。voidwriteUTF(Stringstr)以与机器无关方式使用UTF-8修改版编码将一个字符串写入输出流。数据输入/输出流举例例13-5将一些三角形、矩形数据输出到data1.txt文件中。data1.txt文件格式:图形类型参数1参数2参数3R或r34T或t345思路分析:(1)创建文件输出数据流(outFile),和数据输出数据流(outData)FileOutputStreamoutFile=newFileOutputStream(curPath+/data1.txt);DataOutputStreamoutData=newDataOutputStrea

496、m(outFile);(2)输入图形类型,依据图形类型输入相应参数。将数据写出到数据输出数据流,如此反复若干次。(3)调用outData.flush(),目的是将缓冲区中的数据全部写到文件中。(4)关闭数据输出数据流outData.close(),关闭文件输出数据流outFile.close();代码见书例13-5.数据输入/输出流举例例13-6从文件data1.txt(由例13-5程序产生)中读取图形数据。思路分析:(1)创建文件输入数据流(inFile),和数据输入数据流(intData)FileInputStreaminFile=newFileInputStream(curPath+/d

497、ata1.txt);DataInputStreaminData=newDataInputStream(inFile);(2)读入图形类型等数据。将这些数据输出,如此反复若干次。(3)调用inData.flush(),目的是将缓冲区中的数据全部读到内存。(4)关闭数据输入数据流outData.close(),关闭文件输入数据流outFile.close();代码见书例13-613.2.4对象流对象流包括ObjectOutputStream(对象输出流)和ObjectInputStream(对象输入流)。ObjectOutputStream将Java对象的基本数据类型和属性写到输出流。Object

498、InputStream读取(重构)对象。通过使用流中的文件可以实现对象的持久存储。持久化概念序列化(Serialization)是将对象的状态信息转化成可以存储或传输的信息形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。之后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。在Java语言中,定义的类可以通过实现java.io.Serializable接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口并没有定义方法或字段,仅仅说明定义的类是可序列化的。对象流举例例13-7定义了一矩形类R

499、ectangle13,该类支持序列化接口。 1publicclassRectangle13implementsSerializable2doublea,b;/边长3publicRectangle13(doublea,doubleb)4this.a=a;5this.b=b;67publicdoublegetArea()8doubles;9s=a*b;10returns;1112publicbooleanisRectangle()13return(a0&b0);1415Override16publicStringtoString()17return矩形:+,a=+a+,b=+b+,面积=+this

500、.getArea();1819publicvoidprint()20System.out.println(长方形边长是:+a+,+b);21System.out.println(长方形的面积是+getArea();2223对象流举例例13-8定义测试类ObjectStream1,该类中Input方法的作用是从输入流中读取一些Rectangle13对象,而Output方法的作用则是将这些对象读出到数据文件中。思路分析:Input方法:(1)创建文件输入流inFileStream和对象输入流ibStream。FileInputStreaminFileStream=newFileInputStrea

501、m(curPath+/s1.dat);ObjectInputStreamobStream=newObjectInputStream(inFileStream);(2)从对象输入流ibStream中输入对象:t=(Rectangle13)obStream.readObject();(3)输出对象t。(2)和(3)重复执行若干次。(4)关闭对象输出流obStream,关闭文件输出流。output方法方法:(1)创建文件输出流outFileStream和对象输出流obStream。FileOutputStreamoutFileStream=newFileOutputStream(curPath+/s

502、1.dat);ObjectOutputStreamobStream=newObjectOutputStream(outFileStream);(2)随机产生数据,并创建对象:t=newRectangle13(a,b);/创建矩形类对象。(3)调用将对象obStream.writeObject(t),将对象写入到文件中。(4)关闭对象输出流obStream,关闭文件输出流。13.3基本字符流(1)ASCII码(2)ISO-8859-1ISO组织在ASCII码基础上又制定了一些标准用来扩展ASCII编码,它们分别是ISO-8859-1至ISO-8859-15,其中ISO-8859-1涵盖了大多数西

503、欧语言字符,应用是最为广泛,而ISO-8859-1仍然是单字节编码,它总共能表示 256个字符。(3)GB2312GB2312全称是信息交换用汉字编码字符集基本集,它采用双字节编码,总的编码范围是 A1-F7,其中从A1-A9是符号区,总共包含682个符号, 从B0-F7是汉字区,包含6763个汉字。(4)GBKGBK是汉字内码扩展规范的简称,是中国国家技术监督局为windows95所制定的新的汉字内码规范,它扩展了GB2312,加入更多的汉字,它的编码范围是8140FEFE(去掉XX7F)总共有23940个码位,它能表示21003个汉字,GBK编码与GB2312兼容,也就是说用GB2312编

504、码的汉字可以用GBK来解码。基本字符流(5)GB18030GB18030的全称是信息交换用汉字编码字符集,是我国的强制标准,它可能是单字节、双字节或者四字节编码,它的编码与GB2312编码兼容,该标准虽然是国家标准,但在实际应用过程中,人们使用它并不广泛。(6)UTF-16Unicode(UniversalCode统一码),ISO组织试图想创建一个全新的超语言字典,世界上所有的语言都可以通过这本字典来互译。UTF-16详细定义了Unicode字符在计算机中的存取办法。UTF-16一般用2个字节来表示Unicode转化格式,它是定长表示方法,意思说不论什么字符都可用2个字节来表示,而两个字节即1

505、6个bit,这是UTF-16名字的由来。UTF-16表示字符非常便利,每两个字节表示一个字符,这在字符串操作时就大大简化了操作,这也是Java以UTF-16作为内存的字符存储格式的一个很重要的原因。基本字符流(7)UTF-8UTF-8采用了变长技术,它的每个编码区域有不同的字码长度。不同类型的字符可以是由1至6个字节组成。13.3.2字符集相关的类在java.nio.charset包跟字符集相关的类(Charset、CharsetDecoder、CharsetEncoder、CodeResult、CodingErrorAction);另外,还可用到Buffer类的两个子类(CharBuffer

506、,ByteBuffer,其中CharBuffer是字符缓冲区,而ByteBuffer是字节缓冲区)。字符集相关的类1.Charset类抽象类Charset定义了16位的Unicode码单元序列和字节序列之间的命名映射关系。Charset类的其它主要方法如下:protected Charset(StringcanonicalName,Stringaliases)使用给定的规范名称和别名集合初始化新字符集。Setaliases()返回包含此 charset各个别名的集合。staticSortedMapavailableCharsets()构造从规范charset名称到 charset对象的有序映射

507、。booleancanEncode()判断该字符集是否支持编码。abstractbooleancontains(Charsetcs)判断该字符集是否包含给定的字符集cs。CharBufferdecode(ByteBufferbb)将此 charset中的字节解码成 Unicode字符的便捷方法。staticCharsetdefaultCharset()返回此 Java虚拟机的默认 charset。StringdisplayName()返回此 charset用于默认语言环境的可读名称。ByteBufferencode(CharBuffercb)将此 charset中的 Unicode字符编码成字

508、节的便捷方法。ByteBufferencode(Stringstr)将此 charset中的字符串编码成字节的便捷方法。staticCharsetforName(StringcharsetName)返回命名 charsetName的charset对象。Stringname()返回此charset的规范名称。abstractCharsetDecodernewDecoder()为此 charset构造新的解码器。字符集相关的类例如,创建Charset的对象方法如下:StringcharsetName=utf-16;/指定字符集Charsetcharset1=CharSet.forName(char

509、setName);Charsetcharset2=CharSet.defaultCharSet();使用Charset对象进行编码方法如下:Stringmsg=howtousecharset.;ByteBufferbf=charset1.encode(msg);使用Charset对象进行解码方法如下:CharBuffercf=charset1.decode(bf);字符集相关的类2.CharsetEncoder类CharsetEncoder类主要功能是能够把16位Unicode字符序列转换成特定charset中字节序列。CharsetEncoder类的主要方法有:protectedCharse

510、tEncoder(Charsetcs,floataverageBytesPerChar,floatmaxBytesPerChar,bytereplacement)初始化新的编码器。booleancanEncode(charc)通知此编码器是否能够编码给定的字符。Charsetcharset()返回创建此编码器的charset。ByteBufferencode(CharBufferin)把单个输入字符缓冲区的剩余内容编码到新分配的字节缓冲区的便捷方法。CoderResultencode(CharBufferin,ByteBufferout,booleanendOfInput)从给定输入缓冲区中编

511、码尽可能多的字符,把结果写入给定的输出缓冲区。CoderResultflush(ByteBufferout)刷新此编码器。CharsetEncoderreset()重置此编码器,清除所有内部状态。字符集相关的类例如,利用CharsetEncoder对象编码方法如下:StringcharsetName=utf-16;/指定字符集Charsetcharset1=CharSet.forName(charsetName);CharsetEncodercsEncoder=cs.newEncoder();/得到字符编码器Stringmsg=”howareyou.”;csEncoder.encode(msg

512、);字符集相关的类3.CharsetDecoder类CharsetDecoder类主要功能是把特定字符集中的字节序列转换成16位Unicode字符序列。CharsetDecoder类的主要方法有:protectedCharsetDecoder(Charsetcs,floatavCharsPerByte,floatmaxCharsPerByte)初始化新的解码器。Charsetcharset()返回创建此解码器的charset。CharBufferdecode(ByteBufferin)把单个输入字节缓冲区的剩余内容解码到新分配的字符缓冲区。CoderResultdecode(ByteBuffe

513、rin,CharBufferout,booleanendOfInput)从给定的输入缓冲区中解码尽可能多的字节,把结果写入给定的输出缓冲区。CharsetdetectedCharset()检索此解码器检测到的charset。CoderResultflush(CharBufferout)刷新此解码器。boolean isCharsetDetected()通知此解码器是否已经检测到了一个charset(可选操作)。CharsetDecoderreset()重置此解码器,清除所有内部状态。字符集相关的类例如、利用CharsetDecoder类对象编码方法如下:StringcharsetName=”u

514、tf-16”;/指定字符集Charsetcharset1=CharSet.forName(charsetName);CharsetDecodercsDecoder=cs.newDecoder();/得到字符解码器Stringmsg=howareyou.;csDecoder.Decode(msg);/解码字符集相关的类举例例13-10charset类的应用举例。思路:(1)创建Charset类的对象cs。(2)将字符串使用指定的字符集进行编码。ByteBufferbyteBuffer=cs.encode(我喜欢Java语言.);(3)输出编码后的字节字符串while(byteBuffer.has

515、Remaining()System.out.print(char)byteBuffer.get();(4)将字节缓冲解码成字符缓冲。CharBuffercharBuffer=cs.decode(byteBuffer);(5)输出字符缓冲输出。System.out.println(charBuffer.toString();13.3.3基本字符流Java提供了基本字符流的两个抽象基类Reader和Writer。其中Reader是输入字符流,而Writer是输出字符流。需要注意的是:在Java语言中所使用的字符是指UniCode字符,而不是ACSII字符。抽象类Reader中的主要方法如下:abs

516、tractvoidclose()关闭该流。voidmark(intreadAheadLimit)标记流中的当前位置。boolean markSupported()判断此流是否支持mark()操作。intread()读取单个字符。intread(charcbuf)将字符读入数组。abstractintread(charcbuf,intoff,intlen)将字符读入数组的某一部分。intread(CharBuffertarget)试图将字符读入指定的字符缓冲区。boolean ready()判断是否准备读取此流。voidreset()重置该流。longskip(longn)跳过n个字符。基本字符

517、流抽象类Writer的主要方法如下:Writerappend(charc)将指定字符追加到此writer。Writerappend(CharSequencecsq)将指定字符序列追加到此writer。Writerappend(CharSequencecsq,intstart,intend)将指定字符序列的子序列追加到此writer.Appendable。abstractvoidclose()关闭此流,但要先刷新它。abstractvoidflush()刷新此流。void write(charcbuf)写入字符数组。abstractvoidwrite(charcbuf,intoff,intlen

518、)写入字符数组的某一部分。void write(intc)写入单个字符。void write(Stringstr)写入字符串。void write(Stringstr,intoff,intlen)写入字符串的某一部分。Java提供了常用字符流的子类(实体流和过滤流)。其中Reader类的子类有:InputStreamReader、BufferedReader、CharArrayReader、StringReader、PipeReader以及FilterReader;而抽象类Writer的子类有:OutputStreamWriter、BufferWriter、CharArrayWriter、St

519、ringWriter、PrintWriter以及FilterWriter。13.3.4字节流与字符流转换1.InputStreamReader类InputStreamReader类是字节流通向字符流的桥梁,它负责在输入/输出过程中处理读取字节到字符的转换。字节流与字符流转换InputStreamReader类的构造方法如下:InputStreamReader(InputStreamin)创建一个使用默认字符集的InputStreamReader。InputStreamReader(InputStreamin,Charsetcset)创建使用给定字符集的InputStreamReader。Inp

520、utStreamReader(InputStreamin,CharsetDecoderdec)创建使用给定字符集解码器的InputStreamReader。InputStreamReader(InputStreamin,StringchartsetName)创建使用指定字符集的InputStreamReader。字节流与字符流转换2.OutputStreamWriter类OutputStreamWriter是字符流通向字节流的桥梁:使用指定的字符集将要向其写入的字符编码为字节。它使用的字符集可以由名称指定或显式给定,否则可能接受平台默认的字符集。字节流与字符流转换OutputStreamWri

521、ter的构造方法如下:OutputStreamWriter(OutputStreamout)创建使用默认字符编码的OutputStreamWriter。Java默认字符编码是UTF8。OutputStreamWriter(OutputStreamout,Charsetcs)创建使用给定字符集的OutputStreamWriter。OutputStreamWriter(OutputStreamout,CharsetEncoderenc)创建使用给定字符集编码器的OutputStreamWriter。OutputStreamWriter(OutputStreamout,StringcharsetN

522、ame)创建使用指定字符集的OutputStreamWriter。字节流与字符流转换例13-11从键盘上输入若干行字符内容,将它们保存到文本文件charset1.txt,该文件字符采用utf-16编码方式。分析: (1)创建Scanner对象,并指定可以输入的字符集是GBK。Scannersc=newScanner(System.in,GBK);(2)创建文件输出流ofs。ofs=newFileOutputStream(curPath+/charset1.txt);(3)创建输出指定字符编码的输出字符流。OutputStreamWriteropsWriter=newOutputStreamWr

523、iter(ofs,cs);(4)将字符串写入文件opsWriter.write(msg);(5)关闭输出字符流13.3.5字符文件流Java提供了两个字符文件流,它们分别是FileReader和FileWriter。其中FileReader用来读取字符文件的简单类,它由InputStreamReader继承而来。而FileWriter用来写入字符文件的简单类,它的父类是OutputStreamWriter。1.FileReader类类FileReader类的构造方法如下:FileReader(Filefile)在给定从中读取数据的File的情况下创建一个新FileReader。FileRead

524、er(FileDescriptorfd)在给定从中读取数据的FileDescriptor的情况下创建一个新FileReader。FileReader(StringfileName)在给定从中读取数据的文件名的情况下创建一个新FileReader。2.FileWriter类类FileWriter类的构造方法如下:FileWriter(Filefile,booleanappend)在给出File对象的情况下构造一个FileWriter对象。FileWriter(FileDescriptorfd)构造与某个文件描述符相关联的FileWriter对象。FileWriter(StringfileName

525、,booleanappend)在给出文件名的情况下构造FileWriter对象,字符文件流举例例13-12输入若干行字符,保存到指定文件中。分析:(1)创建Scanner对象,并指定可以输入的字符集是GBK。Scannersc=newScanner(System.in,GBK);(2)创建文件字符输出流。fWriter=newFileWriter(curPath+/fw1.txt);(3)向文件字符输出流输出字符。fWriter.write(msg);(4)关闭文件字符输出流。fWriter.close();字符文件流举例例13-13读取指定文件,并显示该文件内容。分析:(1)创建文件字符输入

526、流。fReader=newFileReader(curPath+/fw1.txt);(2)向文件字符输出流输出字符。fWriter.write(msg);(3)关闭文件字符输出流。fWriter.close();13.4文件与目录操作路径名是一种用分隔符分隔的字符串,路径名有绝对路径名,相对路径名。绝对路径名是完整的路径名,不需要任何其它信息就可以定位到文件。相反,相对路径名必须使用来自其他路径名的信息进行解释。对于Windows平台,包含盘符的路径名的前缀由驱动器名和一个:组成:如果路径名是绝对路径名,后面可能跟着;主机名和共享名是名称序列中的前两个名称。E:2016JavaBookcode

527、1对于UNIX平台,绝对路径名的前缀始终是/。相对路径名没有前缀。表示根目录的绝对路径名的前缀为/并且没有名称序列。文件与目录操作File类主要用于处理文件和文件夹(目录)的相关操作。File类的主要方法:File(Fileparent,Stringchild)根据parent抽象路径名和child路径名字符串创建一个新File实例。File(Stringpathname)通过将给定路径名字符串转换成抽象路径名来创建一个新File实例。File(Stringparent,Stringchild)根据parent路径名字符串和child路径名字符串创建一个新File实例。File(URIuri)

528、通过将给定的file:URI转换成一个抽象路径名来创建一个新的File实例。staticFile createTempFile(Stringprefix,Stringsuffix)在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。staticFile createTempFile(Stringprefix,Stringsuffix,Filedirectory)在指定目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。booleandelete()删除此抽象路径名表示的文件或目录。booleanexists()判断此抽象路径名表示的文件或目录是否存在。FilegetA

529、bsoluteFile()返回抽象路径名的绝对路径名形式。StringgetAbsolutePath()返回抽象路径名的绝对路径名字符串。FilegetCanonicalFile()返回此抽象路径名的规范形式。文件与目录操作String getName()返回由此抽象路径名表示的文件或目录的名称。String getParent()返回此抽象路径名的父路径名的路径名字符串,如果此路径名没有指定父目录,则返回null。FilegetParentFile()返回此抽象路径名的父路径名的抽象路径名,如果此路径名没有指定父目录,则返回null。StringgetPath()将此抽象路径名转换为一个路径

530、名字符串。longlastModified()返回此抽象路径名表示的文件最后一次被修改的时间。longlength()返回由此抽象路径名表示的文件的长度。Stringlist()返回由此抽象路径名所表示的目录中的文件和目录的名称所组成字符串数组。Stringlist(FilenameFilterfilter)返回由包含在目录中的文件和目录的名称所组成的字符串数组,这一目录是通过满足指定过滤器的抽象路径名来表示的。staticFilelistRoots()列出可用的文件系统根目录。booleanmkdir()创建此抽象路径名指定的目录。booleanmkdirs()创建此抽象路径名指定的目录,包

531、括创建必需但不存在的父目录。booleanrenameTo(Filedest)重新命名此抽象路径名表示的文件。booleansetLastModified(longtime)设置由此抽象路径名所指定的文件或目录的最后一次修改时间。booleansetReadOnly()标记此抽象路径名指定的文件或目录,以便只可对其进行读操作。文件与目录操作例13-14查看指定文件或目录相关信息。分析:(1)创建一个新File的实例file。(2)判断file的抽象路径名表示的文件是否是一个标准文件。如果是文件,则输出文件相关信息;否则输出目录相关信息,包括其内内容。文件与目录操作3.文件选择对话框在Swing

532、组件中,JFileChooser是用户选择文件的图形界面对话框。JFileChooser的构造方法:JFileChooser()构造一个指向用户默认目录的JFileChooser。JFileChooser(FilecurDirectory)使用给定的File作为路径来构造一个JFileChooser。JFileChooser(FilecurDirectory,FileSystemViewfsv)使用给定的当前目录和FileSystemView构造一个JFileChooser。JFileChooser(FileSystemViewfsv)使用给定的FileSystemView构造一个JFileC

533、hooser。JFileChooser(StringcurDirectoryPath)构造一个使用给定路径的JFileChooser。JFileChooser(StringcurDirectoryPath,FileSystemViewfsv)使用给定的当前目录路径和FileSystemView构造一个JFileChooser。3.文件选择对话框在Swing组件中,JFileChooser是用户选择文件的图形界面对话框。JFileChooser的构造方法:JFileChooser()构造一个指向用户默认目录的JFileChooser。JFileChooser(FilecurDirectory)使

534、用给定的File作为路径来构造一个JFileChooser。JFileChooser(FilecurDirectory,FileSystemViewfsv)使用给定的当前目录和FileSystemView构造一个JFileChooser。JFileChooser(FileSystemViewfsv)使用给定的FileSystemView构造一个JFileChooser。JFileChooser(StringcurDirectoryPath)构造一个使用给定路径的JFileChooser。JFileChooser(StringcurDirectoryPath,FileSystemViewfsv)

535、使用给定的当前目录路径和FileSystemView构造一个JFileChooser。文件选择对话框JFileChooser类的其它构造方法如下:voidaddChoosableFileFilter(FileFilterfilter)向用户可选择的文件过滤器列表添加一个过滤器。voidchangeToParentDirectory()将要设置的目录更改为当前目录的父级。protectedJDialogcreateDialog(Componentparent)创建并返回包含this的新JDialog,在parent窗体中的parent上居中。FileFiltergetAcceptAllFileF

536、ilter()返回能接收的文件过滤器。FileFilter getChoosableFileFilters()获得用户可选择的文件过滤器列表。FilegetCurrentDirectory()返回当前目录。voidsetCurrentDirectory(Filedir)设置当前目录。StringgetDescription(Filef)返回文件描述。FileFiltergetFileFilter()返回当前选择的文件过滤器。intgetFileSelectionMode()返回当前的文件选择模式。FileSystemViewgetFileSystemView()返回文件系统视图。FileVie

537、wgetFileView()返回当前的文件视图。StringgetName(Filef)返回文件名。FilegetSelectedFile()返回选中的文件。FilegetSelectedFiles()如果将文件选择器设置为允许选择多个文件,则返回选中文件的列表。文件选择对话框voidsetFileFilter(FileFilterfilter)设置当前文件过滤器。voidsetFileHidingEnabled(booleanb)设置是否实现文件隐藏。voidsetFileSelectionMode(intmode)设置JFileChooser,以允许用户只选择文件、只选择目录或者可选择文件

538、和目录。voidsetFileSystemView(FileSystemViewfileSystemView)设置为访问和创建文件系统资源(如查找软驱和获得根驱动器列表),JFileChooser所使用的文件系统视图。voidsetFileView(FileViewfileView)设置用于检索UI信息的文件视图,如表示文件的图标或文件的类型描述。voidsetMultiSelectionEnabled(booleanb)设置文件选择器,以允许选择多个文件。voidsetSelectedFile(Filefile)设置选中的文件。voidsetSelectedFiles(Fileselecte

539、dFiles)如果将文件选择器设置为允许选择多个文件,则设置选中文件的列表。intshowDialog(Componentparent,StringapproveButtonText)弹出具有自定义approve按钮的自定义文件选择器对话框。intshowOpenDialog(Componentparent)弹出一个 “打开文件” 文件选择器对话框。intshowSaveDialog(Componentparent)弹出一个 “另存文件” 文件选择器对话框。在文件操作过程中,需要使用到文件过滤器接口FileFilter。该接口的主要方法包括:booleanaccept(Filepathname

540、)测试指定抽象路径名是否应该包含在某个路径名列表中。文件选择对话框例13-15创建窗体应用程序ViewFile(类文件是ViewFile.java),通过文件对话框选择文本文件,并将该文件显示到文本区域中,当单击保存文件,则可以保存文本区域中的内容,如果单击另存为文件时,则可以将文本区域中的内容,另存为一文件中,该应用程序界面如图所示。文件选择对话框(1)首先,定义了javax.swing.filechooser.FileFilter类的子类MyFileFilter。重载getExtension(Filef)方法,只返回File对象f的文件扩张名。重载publicbooleanaccept(F

541、ilef)方法,当File对象f的文件扩张名是txt或者dat时,则返回true,否则返回false;重载publicStringgetDescription()。(2)选择文件按钮的actionPerformed事件代码.创建JFileChooser对象,并将其将AcceptAll过滤器设置成不作为可用选项。将自定义过滤器对象设为文件选择框的有效过滤器在文件选择框中,当按下确定按钮,进行选择文件操作。(3)保存按钮的actionPerformed事件代码。创建File对象curFile=newFile(fileName);如果curFile文件不存在时,则创建新文件,否则保存文件。(4)另存

542、为按钮的actionPerformed事件代码如下:13.5随机存取文件流随机存取文件跟存储在文件系统中的一个超大字节数组相似,文件指针是指向该隐含数组的光标或索引,类似如图所示;输入操作从文件指针开始位置读取字节,并随着对字节的读取向前移动该文件指针。Java提供了RandomAccessFile类来专门处理随机读取文件操作。RandomAccessFile构造方法如下:RandomAccessFile(Filefile|Stringname,Stringmode)建立从中读取/写入的随机存取文件流,该文件由File参数指定,读写方式由mode参数决定。r、w、rw随机存取文件流Random

543、AccessFile的其它方法如下:FileChannelgetChannel()返回与此文件关联的惟一FileChannel对象。FileDescriptorgetFD()返回与此流关联的不透明文件描述符对象。longgetFilePointer()返回此文件中的当前偏移量。longlength()返回此文件的长度。intread()从此文件中读取一个数据字节。intread(byteb)将最多b.length个数据字节从此文件读入字节数组。intread(byteb,intoff,intlen)将最多len个数据字节从此文件读入字节数组。boolean readBoolean()从该文件读

544、取一个boolean。bytereadByte()从该文件读取一个有符号的八位值。随机存取文件流charreadChar()从该文件读取一个Unicode字符。doublereadDouble()从该文件读取一个double。floatreadFloat()从该文件读取一个float。voidreadFully(bytebytes)将bytes.length个字节从此文件读入字节数组,并从当前文件指针开始。voidreadFully(byteb,intoff,intl)将刚好l个字节从此文件读入字节数组,并从当前文件指针开始。intreadInt()从此文件读取一个有符号的32位整数。Stri

545、ngreadLine()从此文件读取文本的下一行。longreadLong()从此文件读取一个有符号的64位整数。shortreadShort()从此文件读取一个有符号的16位数。intreadUnsignedByte()从此文件读取一个无符号的八位数。intreadUnsignedShort()从此文件读取一个无符号的16位数。StringreadUTF()从此文件读取一个字符串。voidseek(longpos)设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。voidsetLength(longnewLength)设置此文件的长度。随机存取文件流intskipBy

546、tes(intn)尝试跳过输入的n个字节以丢弃跳过的字节。voidwrite(byteb)将b.length个字节从指定字节数组写入到此文件,并从当前文件指针开始。voidwrite(byteb,intoff,intlen)将len个字节从指定字节数组写入到此文件,并从偏移量off处开始。voidwrite(intb)向此文件写入指定的字节。voidwriteBoolean(booleanv)按单字节值将boolean写入到文件。voidwriteByte(intv)按单字节值将byte写入到文件。voidwriteBytes(Strings)按字节序列将该字符串写入到文件。voidwrite

547、Char(intv)按双字节值将char写入该文件,先写高字节。voidwriteChars(Strings)按字符序列将一个字符串写入到文件。voidwriteDouble(doublevalue)使用Double类中的doubleToLongBits方法将双精度参数转换为一个long,然后按八字节数量将该long值写入到文件,先定高字节。voidwriteFloat(floatv)使用Float类中的floatToIntBits方法将浮点参数转换为一个int,然后按四字节数量将该int值写入到文件,先写高字节。voidwriteInt(intv)按四个字节将int写入到文件,先写高字节。v

548、oidwriteLong(longv)按八个字节将long写入到文件,先写高字节。voidwriteShort(intv)按两个字节将short写入到文件,先写高字节。voidwriteUTF(Stringstr)使用UTF-8编码方式将一个字符串写入到文件。voidclose()关闭此随机存取文件流并释放与该流关联的所有系统资源。随机存取文件流例13-16创建一文件RandomFile.java,首先向文件RTest.dat内随机写入10个数据,然后,然后修改文件RTest.dat的第1、3、5、7、9等数据。本章结束!第14章图形、图像本章内容14.1图形14.2绘制图像14.3图像输入/

549、输出14.4绘制组件14.1图形Java类库中的Graphics类和Graphics2D类。其中Graphics类是抽象类,而Graphics2D类是Gaphics类的派生类。Graphics2Dg2d;/绘图组件的Graphics2D对象g2d=(Graphics2D)ob.getGraphics();Graphics2D类的主要方法见书。绘图-Gaphics2D类利用Gaphics2D类对象绘图过程如下:(1)得到Gaphics对象,并将其强制转换成Gaphics2D对象。(2)创建需要绘制的图形(如长方形、线等)。(3)如果需要图形变换(平移、放缩、裁剪等)时,可以调用Gaphics2D

550、对象的setTransform()方法进行设置。(4)设置绘图属性(包括颜色、填充模式等)。(5)最后,调用Gaphics2D对象的draw()、fill()方法进行绘图或填充绘图操作。绘图类-坐标系统绘图颜色设置颜色任何颜色都是由三原色组成(RGB),JAVA中支持24位彩色,即红绿蓝分量取值介于0-255之间(8位表示)。例如,构造一个灰色对象: Colorc1=newColor(205,205,205);或者等于颜色常量:Colorc2=Color.blue;在绘图时,调用Graphcis对象或Graphcis2D对象的setColor(Colorc)方法可以设置画笔颜色。例如,g2d.

551、setColor(c1);绘图颜色设置例14-1创建下图所示窗体应用程序(DrawStyle.java),该程序可以设置颜色、填充模式以及画笔样式,并可以进行绘图和填充绘图。绘图颜色设置例14-1的设置颜色按钮的ActionPerformed事件代码如下:1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2Objectp=红色红色,蓝色蓝色,绿色绿色,黑色黑色;3Objectr=JOptionPane.showInputDialog(null,请选择绘图或填充颜色:请选择绘图或填充颜色:,4颜色设置颜色设置,JO

552、ptionPane.INFORMATION_MESSAGE,null,p,p0);5switch(String)r)6case红色红色:7c=Color.red;break;8case蓝色蓝色:9c=Color.blue;break;10case绿色绿色:11c=Color.green;break;12case黑色黑色:13c=Color.black;1415g2d.setColor(c);/设置绘图或者填充颜色设置绘图或者填充颜色16设置绘图按钮的ActionPerformed事件代码如下:privatevoidjButton4ActionPerformed(java.awt.event.A

553、ctionEventevt)g2d.draw(r);绘图-填充图案Paint接口定义了Graphics2D绘图时的颜色模式。其中填充方式主要有:单色填充、渐变填充以及图案填充方式。在Java语言中,实现了Paint接口的类有:Color、GradientPaint以及TexturePaint。Java2D可以通过Graphics2D类对象的setPaint(Paintp)方法设置绘图时的填充方式。绘图-填充图案GradientPaint提供了使用线性颜色渐变模式填充Shape的方法。GradientPaint(floatx1,floaty1,Colorc1,floatx2,floaty2,Co

554、lorc2)构造一个简单构造一个简单的非周期性的非周期性GradientPaint对象。对象。GradientPaint(floatx1,floaty1,Colorc1,floatx2,floaty2,Colorc2,booleanflag)根据根据flag参数构造一个周期性或非周期性的参数构造一个周期性或非周期性的GradientPaint对象。对象。GradientPaint(Point2Dp1,Colorc1,Point2Dp2,Colorc2)构造一个简单的非周期构造一个简单的非周期性性GradientPaint对象。对象。GradientPaint(Point2Dp1,Colorc1

555、,Point2Dp2,Colorc2,booleanflag)根据根据flag参参数构造一个周期性或非周期性的数构造一个周期性或非周期性的GradientPaint对象。对象。绘图-填充图案TexturePaint类提供一种用被指定为BufferedImage的纹理填充Shape的方式。TexturePaint类的构造方法如下:TexturePaint(BufferedImageim,Rectangle2Dr)构造TexturePaint对象。绘图-填充图案例14-2完善例14-1设置填充方式按钮的ActionPerformed事件代码。1privatevoidjButton2ActionPe

556、rformed(java.awt.event.ActionEventevt)2Objectp=单色填充,渐变填充,纹理填充;3Objectresult=JOptionPane.showInputDialog(null,设置填充方式:,4填充方式设置,JOptionPane.INFORMATION_MESSAGE,null,p,p0);5if(result=null)6return;7switch(String)result)8case单色填充:9g2d.setPaint(c);/设置单色填充10break;11case渐变填充:12GradientPaintgp=newGradientPain

557、t(100,100,Color.BLUE,300,200,Color.MAGENTA);13g2d.setPaint(gp);/设置渐变填充14break;15case纹理填充:16BufferedImageimg=newBufferedImage(100,100,BufferedImage.TYPE_INT_RGB);17try18img=ImageIO.read(newFile(C:netGamesdog1.jpg);19catch(IOExceptionex)20ex.printStackTrace();2122Rectangle2Dr1=newRectangle2D.Double(10

558、0,100,300,200);23TexturePainttp=newTexturePaint(img,r1);24g2d.setPaint(tp);/设置纹理填充2526绘图-设置画笔Java2D可以通过Graphics2D类对象的setStroke(BasicStrokebs)方法设置绘图时的画笔(BasicStroke)。BasicStroke()构造一个具有所有属性的默认值的新构造一个具有所有属性的默认值的新BasicStroke。BasicStroke(floatwidth)构造一个具有指定线条宽度以及构造一个具有指定线条宽度以及cap和和join风格的默认值风格的默认值的实心的实心

559、BasicStroke。有关。有关cap和和join说明见下面参数说明。说明见下面参数说明。BasicStroke(floatwidth,intcap,intjoin)构造一个具有指定属性的实心的构造一个具有指定属性的实心的BasicStroke。BasicStroke(floatwidth,intcap,intjoin,floatlimit)构造一个具有指定属性的实心构造一个具有指定属性的实心的的BasicStroke。绘图-设置画笔例14-3完善例14-1程序,设置画笔按钮代码。1privatevoidjButton3ActionPerformed(java.awt.event.Actio

560、nEventevt)2/TODOaddyourhandlingcodehere:3Stringmsg=1;4msg=JOptionPane.showInputDialog(null,输入线宽输入线宽:);5if(msg=null)6return;7floatw=Float.parseFloat(msg);8bs=newBasicStroke(w,BasicStroke.CAP_ROUND,BasicStroke.JOIN_MITER);9g2d.setStroke(bs);10绘图-设置画笔Java绘图提供了两种绘图模式。(1)覆盖模式(或者称为写模式),将图形像素覆盖当前屏幕上已有像素信息,

561、该模式是默认的绘图模式。覆盖模式可以通过调用Graphics类对象的setPaintMode()方法进行设置。(2)异或模式,将绘制的图形像素与屏幕上该位置的像素信息进行异或运算后,并将结果作为最终的绘图像素信息。该模式可以通过调用Graphics类对象的setXORMode(Colorc)。例14-4完善例14-1代码。设置填充绘图按钮的ActionPerformed事件代码更改如下:1privatevoidjButton6ActionPerformed(java.awt.event.ActionEventevt)2if(jCheckBox1.isSelected()/复选框被选中时,设置为

562、异或绘图模式3g2d.setXORMode(this.getBackground();/异或绘图模式4elseg2d.setPaintMode();/将绘图模式修改可以写模式(即覆盖模式)5g2d.fill(r);6绘制基本图形和文字Java可以绘制各种基本图形,主要包括点、线(包括直线、二次曲线以及三次曲线)、圆弧、椭圆(同时亦包括圆)、矩形以及文字等。1.点Point2D、Point2D.Double、Point2D.Float类定义表示(x,y)坐标空间中的位置的点,其中Point2D是抽象类;Point2D.Double、Point2D.Float是由Point2D派生出来的静态类,其

563、参数精度分别是double、float。2.直线Line2D、Line2D.Double、Line2D.Float都表示线类,其中Line2D是抽象类,Line2D.Double、Line2D.Float是由Line2D派生出来的静态类,Line2D.Double、Line2D.Float参数精度分别是double、float。绘制基本图形和文字Line2D.Double()构造并初始化一个从坐标(0,0)至(0,0)的线,但该线演变成一点。Line2D.Double(doublex1,doubley1,doublex2,doubley2)根据指定坐标构造并初始化Line2D。其中(x1,y1

564、)是直线的起点坐标,而(x2,y2)是直线的终点坐标。Line2D.Double(Point2Dp1,Point2Dp2)根据指定的Point2D对象构造并初始化Line2D。其中p1是直线的起点坐标,而p2是直线的终点坐标。Line2D.Doubleline1,line2;line1=newLine2D.Double(100,100,200,200);line2=newLine2D.Float(100,100,200,200);绘制基本图形和文字3.圆弧Arc2D、Arc2D.Double、Arc2D.Float都表示圆弧类,其中Arc2D是抽象类;Arc2D.Double、Arc2D.Fl

565、oat是由Arc2D派生出来的静态类,其参数精度分别是double、float。圆弧可由边界矩形、起始角度、角跨越(弧的长度)决定。圆弧类型有OPEN、CHORD或PIE,各种圆弧下图所示。(1)PIE形弧 (2)OPEN形弧 (3)CHORD型弧绘制基本图形和文字Arc2D.Double的构造方法如下:Arc2D.Double()构造一个新OPEN弧,并将其初始化为:位置是(0,0)、宽、高大小 为(0,0)、角跨越是(start=0,extent=0)。Arc2D.Double(doublex,doubley,doublew,doubleh,doublestart,doubleextent

566、,inttype)构造一个新弧,并将其初始化为指定的位置、大小、角跨越和闭合类型。Arc2D.Double(inttype)构造一个新弧,并将其初始化为:位置(0,0)、大小(0,0)、角跨越(start=0,extent=0)、指定的闭合类型。Arc2D.Double(Rectangle2DellipseBounds,doublestart,doubleextent,inttype)构造一个新弧,并将其初始化为指定的位置、大小、角跨越和闭合类型。例如,定义如下圆弧例如,定义如下圆弧:Arc2D.Doublearc;arc1=newArc2D.Double(100,100,200,200,0,

567、120,Arc2D.PIE);绘制基本图形和文字二次曲线段QuadCurve2D、QuadCurve2D.Double、QuadCurve2D.Float表示二次参数曲线段类,它们是定义(x,y)坐标空间内的二次参数曲线段。其中QuadCurve2D类是抽象类,QuadCurve2D.Double、QuadCurve2D.Float是由QuadCurve2D派生出来的静态类,其参数精度分别是double、float。绘制基本图形和文字QuadCurve2D.Double的构造方法如下:QuadCurve2D.Double()构造并初始化具有坐标(0,0,0,0,0,0)的二次曲线。QuadCu

568、rve2D.Double(doublex1,doubley1,doublecx,doublecy,doublex2,doubley2)根据指定坐标构造并初始化二次曲线,如图14-4所示。QuadCurve2D.Doublecurve;curve=newQuadCurve2D.Double(100,100,40,80,200,200);绘制基本图形和文字5.立方曲线CubicCurve2D、CubicCurve2D.Double、CubicCurve2D.Float定义(x,y)坐标空间内的三次参数曲线段,其中CubicCurve2D类是抽象类,CubicCurve2D.Double、Cubic

569、Curve2D.Float是由CubicCurve2D派生出来的静态类,其参数精度分别是double、float。CubicCurve2D.Double的构造方法如下:CubicCurve2D.Double()构造并初始化一个具有坐标(0,0,0,0,0,0)的 立方曲线。CubicCurve2D.Double(doublex1,doubley1,doublecx1,doublecy1,doublecx2,doublecy2,doublex2,doubley2)构造并初始化一个具有指定坐标的立方曲线,如下图所示。CubicCurve2D.Doublecurve;curve=newCubicCu

570、rve2D.Double(100,100,40,80,70,90,300,300);绘制基本图形和文字6.椭圆Ellipse2D、Ellipse2D.Double、Ellipse2D.Float类描述由边界矩形定义的椭圆,其中Ellipse2D是抽象类,Ellipse2D.Double、Ellipse2D.Float是由Ellipse2D派生出来的静态类,Ellipse2D.Double、Ellipse2D.Float参数精度分别是double、float。Ellipse2D的构造方法如下:Ellipse2D.Double()构造一个新Ellipse2D,并将其初始化为:位置(0,0)、大小(

571、0,0)。Ellipse2D.Double(doublex,doubley,doublew,doubleh)根据指定坐标构造和初始化Ellipse2D。例如,可以定义如下椭圆:Ellipse2D.Doubleellipse=newEllipse2D.Double(100,200,200,300);Ellipse2D.Doublecircle=newEllipse2D.Double(200,200,100,100);/定义圆绘制基本图形和文字7.矩形Rectangle2D、Rectangle2D.Double、Rectangle2D.Float都表示矩形类,其中Rectangle2D是抽象类,R

572、ectangle2D.Double、Rectangle2D.Float是由Rectangle2D派生出来的静态类,Rectangle2D.Double、Rectangle2D.Float参数精度分别是double、float。Rectangle2D.Double的构造方法如下:Rectangle2D.Double()构造一个新矩形,并将其初始化为:位置(0,0)、大小(0,0)。Rectangle2D.Double(doublex,doubley,doublew,doubleh)根据指定坐标构造和初始化矩形。例如,可以定义如下矩形:Rectangle2D.Doubler,r1;r=newRec

573、tangle2D.Double(100,100,200,300);r1=newRectangle2D.Double(200,200,100,100);/定义圆绘制基本图形和文字8.多边形Polygon类封装了坐标空间中封闭的二维区域的描述。此区域以任意条线段为边界,每条线段都是多边形的一条边。在内部,一个多边形包含一系列坐标对,其中每个坐标对是多边形的一个顶点,且两个连续的坐标对是多边形一条边的端点。第一个和最后一个(x,y)坐标对通过一条线段相连,形成了一个封闭的多边形。Polygon类的主要方法如下:Polygon()创建空的多边形。Polygon(intx,inty,intn)以指定的参

574、数构造并初始化新的Polygon。voidaddPoint(intx,inty)将指定的坐标追加到此Polygon。绘制基本图形和文字9.任意形状GeneralPath类表示根据直线、二次曲线和三次(Bzier)曲线构造的几何路径。它可以包含多个子路径。缠绕规则指定确定路径内部的方式。缠绕规则有EVEN_ODD、NON_ZERO两种类型。(1)EVEN_ODD缠绕规则:从路径外向区域内的点移动并穿过它时,路径的封闭区域在内部区域和外部区域之间交替变化。(2)NON_ZERO缠绕规则:如果从给定点朝任意方向向无穷大绘制射线并检查路径与射线相交的位置,当且仅当路径从左到右穿过射线的次数不等于路径从

575、右到左穿过射线的次数时,点位于路径内。绘制基本图形和文字GeneralPath类的主要方法如下:GeneralPath()构造一个新GeneralPath对象。GeneralPath(intrule)构造一个新GeneralPath对象,使其具有指定缠绕规则以控制需要定义路径内部的操作。GeneralPath(intrule,intn)构造一个新GeneralPath对象,使其具有指定的缠绕规则和指定的初始容量,以存储路径坐标。GeneralPath(Shapes)根据任意Shape对象构造一个新GeneralPath对象。voidappend(PathIteratorpi,booleanco

576、nnect)将指定PathIterator对象的几何形状追加到路径中,可能使用一条线段将新几何形状连接到现有的路径段。voidappend(Shapes,booleanconnect)将指定Shape对象的几何形状追加到路径中,可能使用一条线段将新几何形状连接到现有的路径段。void closePath()通过向最后moveTo的坐标绘制直线闭合当前子路径。绘制基本图形和文字void curveTo(floatx1,floaty1,floatx2,floaty2,floatx3,floaty3)通过绘制与当前坐标及坐标(x3,y3)都相交的Bzier曲线,并将指定点(x1,y1)和(x2,y2

577、)用作Bzier的控制点,将由三个新点定义的曲线段添加到路径中。Point2DgetCurrentPoint()返回最近添加到路径尾部的坐标(作为Point2D对象)。PathIteratorgetPathIterator(AffineTransformat)返回一个沿Shape边界迭代并提供对Shape轮廓几何形状访问的PathIterator对象。PathIteratorgetPathIterator(AffineTransformat,doubleflatness)返回一个沿变平Shape边界迭代并提供对Shape轮廓几何形状的访问的PathIterator对象。intgetWindin

578、gRule()返回填充风格缠绕规则。voidlineTo(floatx,floaty)通过绘制一条从当前坐标到指定坐标的直线在路径中添加点。voidmoveTo(floatx,floaty)通过移动到指定的坐标在路径中添加点。绘制基本图形和文字voidquadTo(floatx1,floaty1,floatx2,floaty2)通过绘制与当前坐标及坐标(x2,y2)都相交的Quadratic曲线,并将指定点(x1,y1)用作二次曲线参数控制点,将由两个新点定义的曲线段添加到路径中。voidreset()将路径重置为空。voidsetWindingRule(intrule)将此路径的缠绕规则设置

579、为指定值。voidtransform(AffineTransformat)使用指定的AffineTransform变换此路径的几何形状。绘制基本图形和文字例14-5创建如图14-6所示窗体应用程序(Draw1.java),绘制线、矩形、椭圆、二次曲线、三次曲线以及文字,其中窗体上的组件如下图所示,所有图形都绘制在面板jPanel1上。图形操作AffineTransform类表示2D仿射变换,它执行从2D坐标到其他2D坐标的线性映射,保留了线的“直线性”和“平行性”。可以使用一系列平移、缩放、翻转、旋转和剪切来构造仿射变换。这样的坐标变换可以使用一个矩阵来表示。此矩阵将源坐标(x,y)变换为目标

580、坐标,其运算方法如下:图形操作AffineTransform类的构造方法如下:AffineTransform()构造恒等变换的AffineTransform。AffineTransform(AffineTransformat)构造一个AffineTransform,让它作为指定的AffineTransform对象的副本。AffineTransform(Tm)根据T精度值数组构造一个AffineTransform,该数组要么保存3x3变换矩阵的4个非平移条目(即),要么保存3x3变换矩阵的6个可指定条目(即)。AffineTransform(Ta00,Ta10,Ta01,Ta11,Ta02,Ta

581、12)根据表示3x3变换矩阵6个可指定条目的6个T精度值构造一个AffineTransform对象。说明:其中T可以是double或者float类型。图形操作设置图形变换绘图步骤如下:(1) 创建一个AffineTransform对象,然后设置相应的图形变换参数。(2)得到组件的Graphics2D对象,并更新该Graphics2D对象的AffineTransform属性。(3)绘制规定的图形。图形操作-举例例14-7 创建窗体如图14-9所示应用程序(Draw2.java),其窗体左边是jPanel1对象,右边是若干个按钮,其下有一标签显示鼠标坐标。图形操作-举例平移变换voidtransl

582、ate(doubletx,doublety)进行平移变换。(2)“平移变换”按钮的ActionPerformed事件代码如下:1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2/TODOaddyourhandlingcodehere:3Stringmsg;4msg=JOptionPane.showInputDialog(null,输入平移量(dx,dy),以逗号分隔:);5if(msg=null)6return;7Stringx=msg.split(,);8if(x.length2)9JOptionPane.s

583、howMessageDialog(null,请输入平移量(dx,dy)!);10g2d.translate(Double.parseDouble(x0),Double.parseDouble(x1);11this.drawFigures();12this.printAffineTransform();13图形操作-举例(3)“旋转变换旋转变换”按钮的按钮的ActionPerformed事件代码如下:事件代码如下:1privatevoidjButton3ActionPerformed(java.awt.event.ActionEventevt)2for(inti=30;i360;i=i+30)3

584、g2d.rotate(i*Math.PI/360.0);/旋转变换旋转变换4this.drawFigures();56this.printAffineTransform();7旋转变换voidrotate(doubletheta)连接此变换与旋转变换,theta的单位是弧度。voidrotate(doubletheta,doublex,doubley)连接此变换与绕锚点(x,y)旋转坐标的(4)“定点旋转变换定点旋转变换”按钮的按钮的ActionPerformed事件代码如下:事件代码如下:1privatevoidjButton8ActionPerformed(java.awt.event.A

585、ctionEventevt)2for(inti=30;i360;i=i+30)3g2d.rotate(i*Math.PI/360.0,p0x,p0y);4this.drawFigures();56this.printAffineTransform();7图形操作-举例voidsetToScale(doublesx,doublesy)将此变换设置为缩放变换。voidscale(doublesx,doublesy)将此变换设为缩放变换。(5)“放大变换放大变换”按钮的按钮的ActionPerformed事件代码如下:事件代码如下:1privatevoidjButton4ActionPerforme

586、d(java.awt.event.ActionEventevt)2/TODOaddyourhandlingcodehere:3AffineTransformaf=newAffineTransform();4af.setToScale(af.getScaleX()*1.5,af.getScaleY()*1.5);/放大变换放大变换5g2d.setTransform(af);6this.drawFigures();7this.printAffineTransform();8(6)“缩小变换缩小变换”按钮的按钮的ActionPerformed事件代码如下:事件代码如下:1 private void

587、jButton5ActionPerformed(java.awt.event.ActionEvent evt) 2 AffineTransform af=new AffineTransform();3 af.setToScale(af.getScaleX()*0.8,af.getScaleY()*0.8);/缩小变换缩小变换4 g2d.setTransform(af);5 this.drawFigures();6 this.printAffineTransform();7 图形操作-举例void setTransform(AffineTransform Tx) 将此变换设置为指定AffineT

588、ransform对象中变换的副本。(7)“默认变换默认变换”按钮的按钮的ActionPerformed事件代码如下:事件代码如下:1privatevoidjButton6ActionPerformed(java.awt.event.ActionEventevt)2AffineTransformaf=newAffineTransform();3g2d.setTransform(af);4this.drawFigures();5this.printAffineTransform();6图形操作-举例(8)剪切变换voidsetToShear(doubleshx,doubleshy)将此变换设置为剪

589、切变换。“剪切变换剪切变换”按钮的按钮的ActionPerformed事件代码如下:事件代码如下:1privatevoidjButton7ActionPerformed(java.awt.event.ActionEventevt)2/TODOaddyourhandlingcodehere:3AffineTransformaf=g2d.getTransform();4Randomrandom=newRandom();5af.setToShear(random.nextDouble(),random.nextDouble();6g2d.setTransform(af);7this.drawFigu

590、res();/绘制图形绘制图形8this.printAffineTransform();9图形操作-举例逆向变换AffineTransformcreateInverse()返回表示逆向变换的AffineTransform对象。(9)“逆向变换逆向变换”按钮的按钮的ActionPerformed事件代码如下:事件代码如下:1privatevoidjButton10ActionPerformed(java.awt.event.ActionEventevt)2AffineTransformaf1=g2d.getTransform(),af2;3try4af2=af1.createInverse();

591、5g2d.setTransform(af2);6catch(NoninvertibleTransformExceptionex)7ex.printStackTrace();89this.drawFigures();10图形运算1.Shape接口Shape接口提供了表示一些几何形状对象的定义。Shape是由PathIterator对象描述的,它可以表示Shape的轮廓以及确定该轮廓如何将2D平面划分成内点和外点的规则。图形运算Shape接口的定义的方法如下:booleancontains(doublex,doubley)测试指定坐标是否在Shape的边界内。booleancontains(dou

592、blex,doubley,doublew,doubleh)测试Shape内部是否完全包含指定矩形区域。booleancontains(Point2Dp)测试指定的点是否在Shape的边界内。booleancontains(Rectangle2Dr)测试Shape内部是否完全包含指定的矩形。RectanglegetBounds()返回一个完全包围Shape的整型Rectangle。Rectangle2DgetBounds2D()返回一个高精度的、比getBounds方法更准确的Shape边界框。PathIteratorgetPathIterator(AffineTransformat)返回一个沿

593、着Shape边界迭代并提供对Shape轮廓几何形状的访问的迭代器对象。PathIteratorgetPathIterator(AffineTransformat,doubleflatness)返回一个沿着Shape边界迭代并提供对Shape轮廓几何形状的平面视图访问的迭代器对象。booleanintersects(doublex,doubley,doublew,doubleh)测试Shape内部是否与指定矩形区域的内部相交。booleanintersects(Rectangle2Dr)测试Shape内部是否与指定Rectangle2D内部相交。图形运算2.区域类Area类是定义任意形状区域。A

594、rea对象是作为对其他封闭区域的几何形状(如矩形、椭圆形和多边形)执行某些二进制CAG(构造区域几何图形,ConstructiveAreaGeometry)操作的对象而定义的。CAG操作包括Add(union)、Subtract、Intersect和ExclusiveOR。例如,一个Area可以由一个矩形区域减去一个椭圆形区域组成。Area类的主要方法如下:Area()创建空区域的默认构造方法。Area(Shapes)Area类可以根据指定的Shape对象创建区域几何形状。voidadd(Arearhs)将指定Area的形状添加到此Area的形状中。voidexclusiveOr(Arearh

595、s)将此Area的形状设置为其当前形状与指定Area形状的组合区域,并减去其交集。图形运算voidintersect(Arearhs)将此Area的形状设置为其当前形状与指定Area形状的交集。booleanintersects(doublex,doubley,doublew,doubleh)测试此Area对象的内部是否与指定矩形区域的内部相交。booleanintersects(Rectangle2Dp)测试此Area对象的内部是否与指定Rectangle2D的内部相交。booleanisEmpty()测试此Area对象是否包括其他区域。booleanisPolygonal()测试此Area

596、是否完全由直边多边形组成。booleanisRectangular()测试此Area的形状是否是矩形。booleanisSingular()测试此Area是否由单个封闭子路径组成。voidreset()从此Area删除所有几何形状,将其恢复为空区域。voidsubtract(Arearhs)从此Area的形状中减去指定Area的形状。voidtransform(AffineTransformt)使用指定的AffineTransform变换此Area的几何形状。例如,可以定义如下代码:Areaa1=newArea();Shapes1=newRectangle2D(100,100,300,300)

597、;Areaa2=newArea(s1);图形运算3.PathIterator接口PathIterator接口允许调用方一次一段地获取边界的路径,为实现Shape接口的对象提供返回其边界几何形状的机制。PathIterator接口中定义的常量如下表所示。类型类型字段名称字段名称字段意义字段意义intSEG_CLOSE指定应该通过将线段追加到与最新SEG_MOVETO对应的点来关闭前面的子路径。intSEG_CUBICTO针对某个3个点的集合,指定要根据最新指定点绘制的三次参数曲线。intSEG_LINETO针对某个点,指定要根据最新指定点绘制的线的结束点。intSEG_MOVETO针对某个点,指

598、定新子路径的起始位置。intSEG_QUADTO针对某对点,指定要根据最新指定点绘制的二次参数曲线。intWIND_EVEN_ODD用于指定确定路径内部的奇偶规则的缠绕规则常量。intWIND_NON_ZERO用于指定确定路径内部的非零规则的缠绕规则常量。图形运算PathIterator接口中的方法有:intcurrentSegment(doublecoords)使用迭代返回当前路径段的坐标和类型。int currentSegment(floatcoords)使用迭代返回当前路径段的坐标和类型。说明:上面两个方法返回值是路径段类型(SEG_MOVETO、SEG_LINETO、SEG_QUADT

599、O、SEG_CUBICTO或SEG_CLOSE)。参数数组coords必须传入长度为6的float或double类型的数组,该数组用于保存返回点的坐标。SEG_MOVETO和SEG_LINETO类型返回一个点,SEG_QUADTO返回两个点,SEG_CUBICTO返回3个点,SEG_CLOSE不返回任何点。intgetWindingRule()返回用于确定路径迭代的缠绕规则。booleanisDone()测试迭代是否完成。图形运算-举例例14-8创建如下图所示窗体应用程序,其窗体左边是jPanel1对象,右边是若干绘制各种图形的按钮。14.2绘制图像Java语言跟绘制图像相关的类和接口主要有I

600、mage类、ImageIcon类、BufferedImage类以及Icon接口等,其中Image类、ImageIcon类、BufferedImage类之间的类层次关系如图所示。绘制图像-ImageIcon类和Icon接口1.ImageIcon类和Icon接口ImageIcon类和Icon接口定义于javax.swing包中,在第11章讲述了ImageIcon类。对于Swing组件,凡是由AbstractButton类继承而来的组件(比如JLabel、JButton等),都从AbstractButton类那里继承了setIcon(Iconicon)方法,并通过setIcon(Iconicon)方

601、法设置组件本身的显示图像,如果参数icon等于null时,则组件不显示图像。绘制图像-ImageIcon类和Icon接口举例例14-10 创建窗体应用程序(DrawImageIcon),如图14-11所示。当点击图片按钮时,则在左边标签中显示图片,而当点击“标签不显示图片”按钮时,则左边标签中不显示图片。绘制图像-ImageIcon类和Icon接口举例(1)创建DrawImageIcon类。1publicclassDrawImageIconextendsjavax.swing.JDialog2publicDrawImageIcon(java.awt.Frameparent,booleanmod

602、al)3super(parent,modal);4initComponents();5Iconim=newImageIcon(C:netGamesimagesOfExamplebutton.jpg);6jButton1.setIcon(im);/设置组件的显示图像78.9(2)图片按钮的ActionPerformed事件代码如下:1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2ImageIconicon=newImageIcon(C:netGamesimagesOfExampledog1.jpg);3jLab

603、el1.setIcon(icon);4(3)标签不显示图片按钮的ActionPerformed事件代码如下:1privatevoidjButton2ActionPerformed(java.awt.event.ActionEventevt)2jLabel1.setIcon(null);3jLabel1.setText(不显示图片);4绘制图像-Image类java.awt包中定义了Image类,它是图像抽象类,所以不能实例化。但可以通过Toolkit类对象的createImage()方法得到Image类对象。Toolkit定义在java.awt包中,它是抽象超类,其子类被用于将各种组件绑定到特

604、定本机工具包实现。大部分组件可通过getToolkit()方法可以得到与之相关的Toolkit对象。Image类的主要方法有:abstractvoidflush()刷新此刷新此Image对象正在使用的所有资源。对象正在使用的所有资源。abstractGraphicsgetGraphics()创建供绘制闭屏图像使用的图形上下文。创建供绘制闭屏图像使用的图形上下文。abstractintgetHeight(ImageObserverobserver)确定图像的高度。确定图像的高度。ImageObserver是接收有关是接收有关Image信息通知的异步更新接口。一般信息通知的异步更新接口。一般Com

605、ment和和JComment组件都实现了组件都实现了ImageObserver接口。接口。ImagegetScaledInstance(intwidth,intheight,inthints)创建此图像的缩放版本。创建此图像的缩放版本。abstractintgetWidth(ImageObserverobserver)确定图像的宽度。确定图像的宽度。绘图类提供了绘图类提供了drawImage()方法可以绘制图像。方法可以绘制图像。绘制图像-BufferImage类BufferImage类描述具有可访问图像数据缓冲区的Image。BufferedImage由图像数据的ColorModel和Ras

606、ter组成。其中ColorModel抽象类封装了将像素值转换为颜色分量(例如,红色、绿色和蓝色)和alpha分量的方法。Raster表示像素矩形数组的类,它定义了占据特定平面矩形区域的像素值,该区表示像素矩形数组的类,它定义了占据特定平面矩形区域的像素值,该区域不一定包括域不一定包括(0,0)。该矩形也称为。该矩形也称为Raster的边界矩形,并且可通过的边界矩形,并且可通过getBounds方方法来获得,它由法来获得,它由minX、minY、width和和height值定义。值定义。minX和和minY值定义了值定义了Raster左上角的坐标。左上角的坐标。Raster的的SampleMod

607、el中中band的数量和类型必须与的数量和类型必须与ColorModel所要求的数量和类所要求的数量和类型相匹配,以表示其颜色和型相匹配,以表示其颜色和alpha分量。所有分量。所有BufferedImage对象的左上角坐标都对象的左上角坐标都为为(0,0)。因此,用来构造。因此,用来构造BufferedImage的任何的任何Raster都必须满足:都必须满足:minX=0且且minY=0。绘制图像-BufferImage类BufferedImage类的主要构造方法如下:BufferedImage(intwidth,intheight,intimageType)构造一个类型为预定义图像类型之一

608、的BufferedImage。BufferedImage(intwidth,intheight,intimageType,IndexColorModelcm)构造一个类型为预定义图像类型之一的BufferedImage:TYPE_BYTE_BINARY或TYPE_BYTE_INDEXED。其中IndexColorModel类是ColorModel的子类。14.3图像输入/输出Java提供了javax.imageio包专门用来处理图像的输入输出问题。javax.imageio包主要有类:ImageReader、ImageWriter、ImageIO;javax.imageio包的主要接口有Ima

609、geInputStream、ImageOutputStream。ImageReader是用来解析和解码图像的抽象超类。在JavaImageI/O框架的上下文中读入图像的类必须创建此类的子类。通常由特定格式的服务提供程序类对ImageWriter对象进行实例化。图像输入/输出2.ImageInputStream接口、ImageOutputStream接口ImageInputStream接口是供ImageReader使用的可查找输入流接口。实现了该接口的类有:FileCacheImageInputStream、FileCacheImageOutputStream、FileImageInputStr

610、eam、FileImageOutputStream、ImageInputStreamImpl、ImageOutputStreamImpl、MemoryCacheImageInputStream、MemoryCacheImageOutputStream。ImageOutputStream是供ImageWriter使用的可查找输出流接口。ImageOutputStream接口与OutputStream类不同的是,ImageOutputStream实现了ImageInputStream接口。图像输入/输出3.ImageIO类ImageIO类包含一些用来读写图像流以及执行简单编码和解码的静态方法。st

611、aticImageInputStreamcreateImageInputStream(Objectob)返回一个ImageInputStream,它将从给定Object中获取输入。staticImageOutputStreamcreateImageOutputStream(Objecto)返回一个ImageOutputStream,它将输出发送到给定Object。staticImageReadergetImageReader(ImageWriterwriter)返回对应于给定ImageWriter的ImageReader(如果有);如果此ImageWriter的插件没有指定相应的ImageRe

612、ader,或者给定ImageWriter没有注册,则返回null。staticImageWritergetImageWriter(ImageReaderr)返回对应于给定ImageReader的ImageWriter(如果有);如果此ImageReader的插件没有指定相应的ImageWriter,或者给定的ImageReader没有注册,则返回null。图像输入/输出staticBufferedImageread(Fileinf)返回一个BufferedImage,作为使用从当前已注册ImageReader中自动选择的ImageReader解码所提供File的结果。staticBuffere

613、dImageread(ImageInputStreamstream)返回一个BufferedImage,作为使用从当前已注册ImageReader中自动选择的ImageReader解码所提供ImageInputStream的结果。staticBufferedImageread(InputStreaminput)返回一个BufferedImage,作为使用从当前已注册ImageReader中自动选择的ImageReader解码所提供InputStream的结果。staticBufferedImageread(URLinput)返回一个BufferedImage,作为使用从当前已注册ImageRe

614、ader中自动选择的ImageReader解码所提供URL的结果。staticbooleanwrite(RenderedImageim,StringformatName,Fileoutput)使用支持给定格式的任意ImageWriter将一个图像写入File。staticbooleanwrite(RenderedImageim,StringformatName,ImageOutputStreamo)使用支持给定格式的任意ImageWriter将一个图像写入ImageOutputStream。图像输入/输出staticboolean write(RenderedImageim,Stringfor

615、matName,OutputStreamoutput)使用支持给定格式的任意ImageWriter将一个图像写入OutputStream。例如,定义如下代码进行读取图像文件:例如,定义如下代码进行读取图像文件:FilefileName=newFile(c:netGamesback1.jpg);ImageInputStreamiis=ImageIO.createImageInputStream(fileName);BufferedImagebi=ImageIO.read(iis);BufferedImageim=ImageIO.read(newFile(“d:animaldog.jpg”);例如

616、,可以定义如下代码写入图像文件:例如,可以定义如下代码写入图像文件:BufferedImagebi;Filef=newFile(c:netGamesback1.jpg);ImageIO.write(im,jpg,f);图像输入/输出-举例例14-12 读写图像文件。完善例14-11的显示图片2按钮和图片另存为按钮的代码。编写编写了读图像文件的了读图像文件的readImage()方法和写入图像文件的方法和写入图像文件的writeImage()方法。方法。1publicBufferedImagereadImage(StringfileName)/fileName是带路径的文件名是带路径的文件名2t

617、ry3returnImageIO.read(newFile(fileName);4catch(Exceptione)5thrownewRuntimeException(e);678/将将BufferedImage对象写到文件中对象写到文件中9publicvoidwriteImage(StringfileName,Stringformat)10try11/读取图像文件读取图像文件12ImageIO.write(RenderedImage)bi,format,newFile(fileName);13catch(Exceptione)14System.out.println();1516图像输入/输

618、出-举例(2)显示图片显示图片2按钮的按钮的ActionPerformed的代码如下:的代码如下:1privatevoidjButton2ActionPerformed(java.awt.event.ActionEventevt)2/读取图像文件读取图像文件3bi=this.readImage(C:netGamesimagesOfExampledog2.jpg);4g2d.drawImage(bi,0,0,jPanel1);/绘制图像绘制图像5(3)图片另存为按钮的图片另存为按钮的ActionPerformed的代码如下:的代码如下:1privatevoidjButton4ActionPerf

619、ormed(java.awt.event.ActionEventevt)2if(bi!=null)3this.writeImage(C:netGamesimagesOfExampleaaa.jpg,jpg);4514.4绘制组件Component类提供了绘制组件相关的主要方法有:(1)paint(Graphicsg):该方法的作用是绘制组件。(2)paintAll(Graphicsg):该方法绘制组件及其所有子组件。(3)repaint():该方法的作用是重绘组件,它需要调用paint()方法或者paintAll()方法。很多时候,需要重载组件的paint(Graphicsg)方法,进行绘图组

620、件。绘制组件-举例例14-13创建五子棋棋盘面板WZQBoard(WZQBoard.java),并建立应用程序(TestWZQ.java),如下图所示。绘制组件-举例思路:(1)创建父类是Jpanel的子类WZQBoard,并添加WZQBoard的属性。1publicclassWZQBoardextendsjavax.swing.JPanel2privateintwidth,height;/棋盘宽度和高度棋盘宽度和高度3booleanselected;/当前是否有棋子选中当前是否有棋子选中4intstartPx,startPy;/选中的棋子的开始位置选中的棋子的开始位置5intendPx,en

621、dPy;/选中的棋子,最后走的位置。选中的棋子,最后走的位置。6StringfName;/棋盘背景文件名字棋盘背景文件名字7ColorcolorOfLine;8publicWZQBoard()9initComponents();10fName=back_chineseChess10.jpg;11colorOfLine=Color.BLACK;1213绘制组件-举例(2)编写画五子棋棋盘方法publicvoiddrawWZQBoard(Graphics2Dg)。该方法主要完成工作。(3)编写设置背景图方法。13/更新背景图像更新背景图像14publicvoidupdateBackground(S

622、tringfileName)15fName=fileName;16this.update(this.getGraphics();1718/设置背景设置背景19publicvoidsetBackPicture(Graphicsg,StringfileName)20intx=0,y=0;21intw,h;22w=this.getWidth();23h=this.getHeight();24Stringdirectory=c:/netGames/+imagesOfExample/;25ImageIconicon=newImageIcon(directory+fileName);26g.drawIma

623、ge(icon.getImage(),x,y,w,h,this);/设置背景图片设置背景图片27绘制组件-举例(4)编写publicvoidpaint(Graphicsg1)。52publicvoidpaint(Graphicsg1)53width=(int)(this.getWidth()/20);/计算五子棋每格宽度计算五子棋每格宽度54height=(int)(this.getHeight()/20);/计算五子棋每格高度计算五子棋每格高度55setBackPicture(g1,fName);/设置棋盘背景图片设置棋盘背景图片56Graphics2Dg=(Graphics2D)g1;57

624、/画五子棋棋盘画五子棋棋盘58drawWZQBoard(g);59绘制组件-举例(5)编译当前项目后,产生项目类包。将创建的五子棋面板类WZQBoard加入到Netbeans的组件面板上。本章结束!第15章线程本章内容15.1进程和线程的概念15.2线程定义15.3线程状态15.4守护线程15.5线程调度15.6线程通信15.7定时器15.8Java进程15.1进程和线程的概念进程是具有一独立功能的程序关于某种数据集合的一次运行活动。进程和线程的概念线程,亦称为轻量级进程(LightweightProcess),它是程序执行过程路线的最小单元。一般线程由线程编号、当前指令指针(PC)、寄存器集

625、合和堆栈组成。线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不能拥有系统资源,只拥有一部分在运行中必不可少的资源,但它可与同属一个进程的其他线程共同享有该进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。进程和线程的概念在Java中,线程主要由三部分构成:(1)虚拟CPU,它控制中线程的运行,主要由Thread类实现。(2)执行代码,线程的功能由此代码决定,由Thread类控制该代码依次执行。(3)各种数据,它们被传给线程Thread类。15.2线程定义1.Thread类在Java语言中,定义的线程类是Thread。Thread类

626、的主要方法如下:Thread()创建新的Thread对象。Thread(Runnabletarget,Stringname)创建新的Thread对象,其中target是线程的运行对象,name是线程名称。Thread(ThreadGroupgroup,Runnabletarget,Stringname,longstackSize)创建新的Thread对象,以便将target作为其运行对象,将指定的name作为其名称,作为group线程组的一员,并具有指定的堆栈尺寸。Thread(ThreadGroupgroup,Stringname)创建新的Thread对象。staticintactiveCo

627、unt()返回当前线程的线程组中活动线程的数目。staticThreadcurrentThread()返回对当前正在执行的线程对象的引用。staticintenumerate(Threadtarray)将当前线程的线程组及其子组中的每一个活动线程复制到指定的数组中。线程定义longgetId()返回该线程的标识符。StringgetName()/setName(Stringname)返回/设置该线程的名称。intgetPriority()/setPriority(intn)返回/设置线程的优先级。Thread.StategetState()返回该线程的状态。ThreadGroupgetThre

628、adGroup()返回该线程所属的线程组。voidinterrupt()中断线程。staticBooleaninterrupted()测试当前线程是否已经中断。voidjoin()等待该线程终止。voidjoin(longm,intn)等待该线程终止的时间最长为m毫秒+n纳秒。voidrun()如果该线程是使用独立的Runnable运行对象构造的,则调用该Runnable对象的run方法;否则,该方法不执行任何操作并返回。voidsetDaemon(booleanyn)将该线程标记为守护线程或用户线程。staticvoidsleep(longm,intn)在指定的毫秒数加指定的纳秒数内让当前正

629、在执行的线程休眠(暂停执行),n默认值是0。voidstart()使该线程开始执行。这时Java虚拟机调用该线程的run方法。staticvoidyield()暂停当前正在执行的线程对象,并执行其他线程。线程定义2.Runnable接口Runnable接口应该由那些打算通过某一线程执行其实例的类来实现。实现了Runnable接口的类必须定义一个称为run()的无参数方法。线程定义3.ThreadGroup类ThreadGroup是线程组,它表示线程的集合。定义线程组的目的:是对一批线程进行分类管理。当然,线程组也可以包含其他线程组。线程组构成一棵树,在树中,除了初始线程组外,每个线程组都有一个

630、父线程组。ThreadGroup类的构造方法如下:ThreadGroup(Stringname)创建一个新线程组,其中name是线程组名称。ThreadGroup(ThreadGroupparent,Stringname)创建一个新线程组。其中parent指定父线程组,name是线程组名称。线程定义ThreadGroup类中其他主要方法:intactiveCount()返回此线程组中活动线程的估计数。intactiveGroupCount()返回此线程组中活动线程组的估计数。voiddestroy()销毁此线程组及其所有子组。intenumerate(Threadlist,booleanr)把

631、此线程组中的所有活动线程复制到指定数组中。intenumerate(ThreadGrouplist,booleanr)把对此线程组中的所有活动子组的引用复制到指定数组中。intgetMaxPriority()返回此线程组的最高优先级。StringgetName()返回此线程组的名称。ThreadGroupgetParent()返回此线程组的父线程组。voidlist()将有关此线程组的信息输出到标准输出。voidsetDaemon(booleandaemon)更改此线程组的后台程序状态。voidsetMaxPriority(intpri)设置线程组的最高优先级。线程定义4.定义线程方法(1)创

632、建)创建Thread的子类,并重载该子类的子类,并重载该子类Thread类的类的run方法。方法。class子线程名称子线程名称extendsThreadpublicvoidrun()(2)创建类,且该类实现)创建类,且该类实现Runnable接口,并重载方法接口,并重载方法run()。class线程名称线程名称implementsRunnablepublicvoidrun()线程定义(3)创建Runnable接口的对象,然后利用该对象作为参数,创建Thread对象。Runnabler=newRunnable()publicvoidrun();Threadt=newThread(r);线程定义

633、-举例例15-1创建判断一个数是否是素数的线程类PrimeThread1和PrimeThread2。classPrimeThread1extendsThreadlongn;PrimeThread1(longn)this.n=n;publicvoidrun()/判断数判断数n是否是素数是否是素数.classPrimeThread2implementsRunnablelongn;PrimeThread1(longn)this.n=n;publicvoidrun()/判断数判断数n是否是素数是否是素数.15.3线程状态在Java中,线程可以处于下列任何一种状态。NEW(新创建的未运行线程):至今尚未

634、启动的线程处于这种状态。RUNNABLE(运行):正在Java虚拟机中执行的线程处于这种状态。BLOCKED(阻塞):受阻塞并等待某个监视器锁的线程处于这种状态。WAITING(等待):无限期地等待另一个线程来执行某一特定操作的线程处于这种状态。TIMED_WAITING(有限等待):等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态。TERMINATED(终止):已退出的线程处于这种状态。线程状态线程状态1.创建线程(NEW)在Java语言中,可以通过线程类Thread或者Thread的子类构造方法创建线程。2.可运行状态(RUNNABLE)线程中处于运行run()方法,线程从其

635、他状态到此状态是调用start()方法。3.终止状态(TERMINATED)当线程run()执行结束返回时,线程自动终止。在程序执行过程中,不建议调用线程类的stop()方法来终止线程,该方法具有不安全性。线程状态4.等待状态(WAITING和TIMED_WAITING)在Java中,当线程在执行过程,由于某些原因被暂停执行,这时可以调用线程sleep()方法,就可以进入等待状态(等待状态包括WAITING和TIMED_WAITING两种状态)。如果线程被永远暂停时,该线程就进入WAITING状态。如果线程仅仅等待一段时间,过段时间后,又会被调用,这时,该线程进入TIMED_WAITING状态

636、。线程状态5.阻塞(Blocked)线程已经被挂起,它“睡着”了,原因通常是它在等待一个“锁”,当尝试进入一个synchronized语句块/方法时,锁已经被其他线程占有,就会被阻塞,直到另一个线程走完临界区或发生了相应锁对象的wait()操作后,它才有机会去争夺进入临界区的权利。例15-2完善例15-1的PrimeThread1类,完善例15-1的PrimeThread2类。例15-3利用Thread创建线程,该线程的主要作用是:输入一个数,判断该数是奇数,还是偶数。并输出主线程所在线程组信息。线程状态15.4守护线程在Java中有两类线程:即用户线程(UserThread)和守护线程(Da

637、emonThread)。通俗地说,任何一个守护线程都是整个JVM中所有用户线程的大管家。将用户线程设为守护线程的办法是调用Thread类的setDaemon(true)方法。将线程t设为守护线程时,编程者应该注意以下几点:(1)t.setDaemon(true)必须在t.start()之前调用,否则会发生IllegalThreadStateException异常。原因是你不能把正在运行的常规线程设为守护线程。 (2)守护线程应该永远不去访问系统资源,如数据库、文件等,因为它会在任何时候甚至正在进行某种操作时,发生中断。(3)而守护线程在运行期间定义并由守护线程创建的线程,都自然而然地都是守护线

638、程。线程状态-举例例15-5创建守护线程类的测试类DaemonTest,在其静态方法main()中创建守护线程类DaemonThread;而守护线程类DaemonThread在运行使创建SubThread线程类。SubThread类主要功能是随机产生两个0到100以内的整数,并求它们的最大公约数。15.4守护线程在Java中有两类线程:即用户线程(UserThread)和守护线程(DaemonThread)。守护线程的作用是为其他线程的运行提供便利服务,它就是一个很称职的守护者。将用户线程设为守护线程的办法是调用Thread类的setDaemon(true)方法。将线程t设为守护线程时,编程者

639、应该注意以下几点:(1)t.setDaemon(true)必须在t.start()之前调用,否则会发生IllegalThreadStateException异常。原因是你不能把正在运行的常规线程设为守护线程。 (2)守护线程应该永远不去访问系统资源,如数据库、文件等,因为它会在任何时候甚至正在进行某种操作时,发生中断。(3)而守护线程在运行期间定义并由守护线程创建的线程,都自然而然地都是守护线程,15.5线程调度java中每一个线程都有优先级属性,在默认情况下,新建的线程的优先级与创建该线程的线程优先级相同。线程优先级的值是一个整数,其值范围在区间1,10内。而且在Thread类中定义了三个常

640、量:NORM_PRIORITY(默认优先级,值为5)、MIN_PRIORITY(最低优先级,值为1)以及MAX_PRIORITY(最高优先级,值为10)。在Java语言中,通过线程Thread类的setPriority()方法改变线程的优先级,并且通过线程Thread类的getPriority()方法来得到线程的优先级。线程调度例15-5 创建守护线程类的测试类DaemonTest,在其静态方法main()中创建守护线程类DaemonThread;而守护线程类DaemonThread在运行使创建SubThread线程类。SubThread类主要功能是随机产生两个0到100以内的整数,并求它们的

641、最大公约数。15.6线程通信在多线程的实际运行过程中,这些线程之间需要共享数据、共同协作、相互通信才能完成它各自的任务。线程通信的方式有:(1)循环查询条件方式;(2)线程同步;(3)等待/通知机制。15.6.1循环查询方式在循环查询方式下,假定存在两个线程thread1和thread2,线程thread1不断地更改条件,另一线程thread2则不停地通过循环语句判断条件是否成立,由此实现线程间的通信。循环查询方式,对于多线程(超过2个)相互通信,还会引起混乱。15.6.2线程同步如下图所示,在某数据库中,存在图书表book,该表经常被多个线程同时修改和访问,线程A、线程B、线程C都进行还书操

642、作,而线程D进行借书操作,假定它们都要操作的对象是图书编号为W0019的记录。线程同步1publicclassData2privateintd1=0;3privateintd2=0;4privatestaticlongcount=0;5publicData()6publicData(Datad)7d1=d.d1;8d2=d.d2;910/线程线程t修改数据方法修改数据方法11publicvoideditData(intd,Threadt)12d1=d;13d2=d;14count+;15if(d1!=d2)16System.out.println(t.getName()+发现:第发现:第+co

643、unt+次信息出现不一致次信息出现不一致);171819线程同步1publicclassEditDataThreadextendsThread2Datad;/定义要修改的数据定义要修改的数据3/构造方法构造方法4publicEditDataThread(Datad,Stringname)5super(name);6this.d=d;/注意此处属性注意此处属性d是参数是参数d的引用,主要目的是为了多线程共享。的引用,主要目的是为了多线程共享。78Override9publicvoidrun()10while(true)1112/随机产生随机整数,范围在随机产生随机整数,范围在(0,1000)13

644、intn=(int)(Math.random()*1000);14d.editData(n,this);/修改数据修改数据data1516171publicclassNoSameDataTest2publicstaticvoidmain(Stringargs)3Datadata=newData();/共享数据共享数据4EditDataThreadt=newEditDataThread10;/线程数组线程数组5inti;6for(i=0;i10;i+)7ti=newEditDataThread(data,线程线程A+(i+1);8System.out.println(测验开始测验开始.);9fo

645、r(i=0;i10;i+)10ti.start();/启动线程启动线程1112线程同步同步概念所以,当多线程访问共享数据时,在任意时刻,只有且只有一个线程以独占方式访问共享的数据。而这种访问数据的方式,被称之为同步。为了实现线程同步,Java语言引进了锁的概念。在Java语言中,每个对象和方法都只有一把锁,只要有线程来访问它,就会上锁。其他所有线程在此期间中,都无法访问已上锁的对象或方法。线程同步Java语言提供的锁就是synchronized和Lock接口。Lock接口提供了与synchronized关键字类似的同步功能,但需要编程者在使用时手动获取锁和释放锁。而且Lock接口还有四个非常强

646、大的实现类(ReentrantLock、ReentrantReadWriteLock、ReentrantReadWriteLock.ReadLock和ReentrantReadWriteLock.WriteLock)。重入锁就是当前持有该锁的线程能够多次获取该锁,无需等待。ReentrantLock是重入锁。ReentrantReadWriteLock是可读可写锁,该类使用两把锁来解决问题,一把锁是读锁,一把锁是写锁。ReentrantReadWriteLock.ReadLock是可读锁,而ReentrantReadWriteLock.WriteLock是可写锁。synchronized实现同

647、步synchronized实现锁的方法有两种:方法一:synchronized返回值类型 方法名称(参数列表)/方法的代码实现说明:上面结构是实现方法同步。方法二:synchronized(对象名)对象名.fun();/调用对象的操作方法fun()synchronized实现同步-举例例15-9利用synchronized修饰方法,避免发生不一致情况。1publicclassData12privateintd1=0;3privateintd2=0;4privatestaticlongcount=0;5publicData1()6publicData1(Data1d)7d1=d.d1;8d2=d

648、.d2;910/线程线程t修改数据方法修改数据方法11publicsynchronizedvoideditData(intd,Threadt)12d1=d;13d2=d;14count+;15if(d1!=d2)16System.out.println(t.getName()+发现:第发现:第+count+次信息出现不一致次信息出现不一致);1718191publicclassEditDataThread1extendsThread2Data1d;/定义要修改的数据定义要修改的数据3/构造方法构造方法4publicEditDataThread1(Data1d,Stringname)5super

649、(name);6this.d=d;/注意此处属性注意此处属性d是参数是参数d的引用,主要目的是为了多线程共享。的引用,主要目的是为了多线程共享。78Override9publicvoidrun()10while(true)1112/随机产生随机整数,范围在随机产生随机整数,范围在(0,1000)13intn=(int)(Math.random()*1000);14d.editData(n,this);/修改数据修改数据data1516171publicclassSameDataTest12publicstaticvoidmain(Stringargs)3Data1data1=newData1(

650、);/共享数据共享数据4EditDataThread1t=newEditDataThread110;/线程数组线程数组5inti;6for(i=0;i10;i+)7ti=newEditDataThread1(data1,线程线程A+(i+1);8System.out.println(测验开始测验开始.);9for(i=0;i10;i+)10ti.start();/启动线程启动线程1112synchronized实现同步-举例例15-10利用synchronized修饰对象,实现同步。在此处,只将例15-9中的(1)EditDataThread1修改成如下形式:1publicclassEditD

651、ataThreadextendsThread2Datad;/定义要修改的数据定义要修改的数据3/构造方法构造方法4publicEditDataThread(Datad,Stringname)5super(name);6this.d=d;/注意此处属性注意此处属性d是参数是参数d的引用,主要目的是为了多线程共享。的引用,主要目的是为了多线程共享。78Override9publicvoidrun()10while(true)1112/随机产生随机整数,范围在随机产生随机整数,范围在(0,1000)13intn=(int)(Math.random()*1000);14synchronized(d)1

652、5d.editData(n,this);/修改数据修改数据data1617181915.6.2.2Lock接口实现同步Lock接口定义的方法如下:voidlock()获取锁。voidlockInterruptibly()获取锁,除非当前线程被中断。ConditionnewCondition()返回绑定到Lock实例的新Condition实例。booleantryLock()只有在调用时空闲时,才可以获得锁。boolean tryLock(longtime,TimeUnitunit)如果在规定的等待时间是空闲的,并且当前线程没有被中断,则可以获取该锁。voidunlock()释放锁。Lock接口

653、实现同步Lock接口实现锁的方法如下:(1)首先定义锁LocklockName=;例如,可以是lockName=newReentrantLock();或者lockName=newLock();(2)定义方法修饰符 方法名称(参数列表)lockName.lock();/加锁try/由锁保护的代码。finallylockName.unlock();/解锁Lock接口实现同步-举例例15-11利用Locked实现线程同步操作。1publicclassData22privatefinalLocklock=newReentrantLock();/定义锁3privateintd1=0;4privatein

654、td2=0;5privatestaticlongcount=0;6publicData2()7publicData2(Data2d)8d1=d.d1;9d2=d.d2;1011/线程t修改数据方法12publicvoideditData(intd,Threadt)13lock.lock();/加锁14try1516d1=d;17d2=d;18count+;19if(d1!=d2)20System.out.println(t.getName()+发现:第+count+次信息不一致);2122finally23lock.unlock();/解锁242526Lock接口实现同步-举例1publicc

655、lassEditDataThread2extendsThread2Data2d;/定义要修改的数据定义要修改的数据3/构造方法构造方法4publicEditDataThread2(Data2d,Stringname)5super(name);6this.d=d;/注意此处属性注意此处属性d是参数是参数d的引用,主要目的是为了多线程共享。的引用,主要目的是为了多线程共享。78Override9publicvoidrun()1011while(true)1213/随机产生随机整数,范围在随机产生随机整数,范围在(0,1000)14intn=(int)(Math.random()*1000);15d

656、.editData(n,this);/修改数据修改数据data161718publicstaticvoidmain(Stringargs)19Data2data=newData2();/共享数据20EditDataThread2t=newEditDataThread210;/线程数组21inti;22for(i=0;i10;i+)23ti=newEditDataThread2(data,线程A+(i+1);24System.out.println(测验开始.);25for(i=0;i0)13balance=balance+num;14returntrue;1516else17returnfal

657、se;1819publicbooleandrawMoney(floatnum)20if(balance-num0)/存钱成功时,返回存钱成功时,返回true21balance=balance-num;22returntrue;2324else/没有成功时,就返回没有成功时,就返回false25returnfalse;2627Person类等待/通知机制-举例1publicclassTestPersonThread2publicstaticvoidmain(Stringargs)3Accountaccount=newAccount();/创建账户创建账户4Personalice=newPerso

658、n(Alice,account,MoneyFlag.SAVE);5Personbob=newPerson(Bob,account,MoneyFlag.DRAW);6System.out.println(当前当前+account);7alice.start();/启动存钱线程启动存钱线程8bob.start();/启动取钱线程启动取钱线程910在实践编程过程中,很多时候需要按预定时间计划执行应用程序。而Java语言中,就提供了两个Timer类(一个在java.util包和javax.swing.Timer包)、TimerTask类。1.java.util包中定义的Timer类在java.util

659、包中定义了定时器类Timer,主要用于安排执行一次任务,或者定期重复执行指定任务。该类的主要方法如下:Timer()创建一个新计时器。Timer(booleanisDaemon)创建一个新计时器,可以指定其相关的线程作为守护程序运行。Timer(Stringname)创建一个新计时器,其相关的线程具有指定的名称。Timer(Stringname,booleanisDaemon)创建一个新计时器,其相关的线程具有指定的名称,并且可以指定作为守护程序运行。voidcancel()终止此计时器,丢弃所有当前已安排的任务。intpurge()从此计时器的任务队列中移除所有已取消的任务。15.7定时器定

660、时器voidschedule(TimerTasktask,Datetime)安排在指定的时间执行指定的任务。voidschedule(TimerTasktask,DatefirstTime,longperiod)安排指定的任务在指定的时间开始进行重复的固定延迟执行。voidschedule(TimerTasktask,longdelay)安排在指定延迟后执行指定的任务。voidschedule(TimerTasktask,longdelay,longperiod)安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。voidscheduleAtFixedRate(TimerTasktask,

661、DatefirstTime,longperiod)安排指定的任务在指定的时间开始进行重复的固定速率执行。voidscheduleAtFixedRate(TimerTasktask,longdelay,longperiod)安排指定的任务在指定的延迟后开始进行重复的固定速率执行。定时器2.TimerTask类在java.util包中还定义了TimerTask类,它是由Timer安排为一次执行或重复执行的任务。该类的主要方法如下:protectedTimerTask()创建一个新的计时器任务。booleancancel()取消此计时器任务。abstractvoidrun()此计时器任务要执行的操作

662、。longscheduledExecutionTime()返回此任务最近实际执行的安排执行时间。定时器使用定时器方法如下:(1)先定义TimerTask任务类的子类,重新定义run()方法;(2)定义Timer类的对象t;(3)调用Timer对象t的schedule方法,安排在指定时间执行指定任务;(4)如果要取消定时器,则可以调用调用Timer对象t的cancel()方法。例15-13Timer和TimerTask类的使用举例。(TimerTest2.java)定时器3.javax.swing包中定义的Timer类在Java开发包中,java.util.Timer类和javax.swing.

663、Timer两者都提供相同的基本功能,但是java.util.Timer更常用,功能更多。但javax.swing.Timer有两个特征,它们可以让使用GUI更方便。首先,其事件处理程序为GUI程序员所熟悉并且可以更容易地处理事件指派线程。第二,其自动线程共享意味着不必采取特殊步骤来避免生成过多线程。定时器javax.swing.Timer的主要方法如下:Timer(intdelay,ActionListenerlistener)创建一个每delay毫秒将通知其侦听器的Timer。intgetDelay()返回两次激发操作事件之间的延迟,以毫秒为单位。intgetInitialDelay()返回

664、该定时器的初始延迟。voidsetInitialDelay(intinitialDelay)设置定时器的初始延迟,默认情况下与两次事件之间的延迟相同。voidsetRepeats(booleanflag)如果flag为false,则指示定时器只向其侦听器发送一次动作事件。boolean isRunning()如果该定时器正在运行,则返回true。voidrestart()重新启动Timer,取消所有挂起的激发并使它激发其初始延迟。voidsetDelay(intdelay)设置Timer延迟,两次连续的操作事件之间的毫秒数。voidstart()启动该Timer,以使它开始向其侦听器发送操作事

665、件。voidstop()停止该Timer,以使它停止向其侦听器发送操作事件。定时器说明:创建javax.swing.Timer对象需要做到:(1)需要创建ActionListener接口的引用或者实现了ActionListener接口的类,并实现其actionperformed(ActionEvente)方法。(2)然后通过Timer(intdelay,ActionListenerlistener)创建定时器对象。定时器-举例例15-14创建如图15-5所示窗体应用程序(ViewTime),当单击开始按钮时,每隔一秒显示当前时间到标签(该标签有线边框修饰);当单击结束按钮时,则停止显示当前时间

666、。定时器-举例(1)编写任务类编写任务类MyAction,其代码如下:其代码如下:1publicclassMyActionimplementsActionListener2JLabellabel;/定义了一标签属性定义了一标签属性3/构造方法构造方法4publicMyAction(JLabell)5this.label=l;67Override8publicvoidactionPerformed(ActionEvente)9Calendarc=Calendar.getInstance();10/定义简单日期格式定义简单日期格式11SimpleDateFormatf=newSimpleDateF

667、ormat(yyyy年年MM月月dd日日HH时时mm分分ss秒秒);12/得到当前时间的简单日期格式字符串得到当前时间的简单日期格式字符串13Strings=f.format(c.getTime();14label.setText(s);1516定时器-举例(2)定义窗体应用程序定义窗体应用程序ViewTime,其代码如下:,其代码如下:1importjavax.swing.Timer;2publicclassViewTimeextendsjavax.swing.JDialog3Timertimer;/定时器定时器4publicViewTime(java.awt.Frameparent,boo

668、leanmodal)5super(parent,modal);6initComponents();7/创建定时器对象,每隔秒,执行任务创建定时器对象,每隔秒,执行任务MyAction8timer=newTimer(1000,newMyAction(jLabel1);/910.(3)定义开始按钮和结束按钮,其代码如下:定义开始按钮和结束按钮,其代码如下:1privatevoidjButton1ActionPerformed(java.awt.event.ActionEventevt)2timer.start();34privatevoidjButton2ActionPerformed(java.

669、awt.event.ActionEventevt)5timer.stop();6715.8Java进程Java语言中,除了用到线程之外,还需要使用进程。有关进程使用情况,主要涉及到ProcessBuilder、Runtime、Process以及System等个类。15.8.1ProcessBuilderProcessBuilder类用于创建操作系统进程。每个进程属性包括:(1)命令,它是一个字符串列表,表示要调用的外部程序文件及其参数(如果有);(2)环境,它是从变量到值的依赖于系统的映射。初始值是当前进程环境的一个副本(可以参考System.getenv())。(3)工作目录,默认值是当前进

670、程的当前工作目录,通常可以根据系统属性user.dir来命名;(4)redirectErrorStream属性。开始时,此属性为false,意思是子进程的标准输出和错误输出被发送给两个独立的流,这些流可以通过Process.getInputStream()和Process.getErrorStream()方法来访问。如果将值设置为true,标准错误将与标准输出合并。这使得关联错误消息和相应的输出变得更容易。在此情况下,合并的数据可从Process.getInputStream()返回流中读取,而从Process.getErrorStream()返回的流读取将直接到达文件尾。Java进程Proc

671、essBuilder类的构造方法如下:ProcessBuilder(Listcommand)利用指定的操作系统程序和参数构造一个进程生成器。ProcessBuilder(Stringcommand)利用指定的操作系统程序和参数构造一个进程生成器。ProcessBuilder类的主要方法如下:Listcommand()返回此进程生成器的操作系统程序和参数。ProcessBuildercommand(Listcommand)设置此进程生成器的操作系统程序和参数。ProcessBuildercommand(Stringcommand)设置此进程生成器的操作系统程序和参数。Filedirectory(

672、)返回此进程生成器的工作目录。Processstart()使用此进程生成器的属性启动一个新进程。Java进程例15-15创建一进程,该进程运行记事本程序,并打开进程程序文件所在位置的文件file1.txt,如果该文件不存在,则创建该文件。1publicclassStartNote2publicstaticvoidmain(Stringargs)throwsIOException3/创建进程生成器创建进程生成器4ProcessBuilderpb=newProcessBuilder(C:Windowssystem32notepad.exe,file.txt);5/利用进程生成器创建进程,并启动该进

673、程利用进程生成器创建进程,并启动该进程6Processp=pb.start();78Java进程15.8.2Runtime类在Java语言中,每个Java应用程序都有一个Runtime类实例,使应用程序能够与其运行的环境相连接。应用程序不能创建自己的Runtime类实例,但是编程者可以利用getRuntime方法获取当前运行时。Runtime类中的主要方法如下:voidaddShutdownHook(Threadhook)注册新的虚拟机来关闭挂钩。intavailableProcessors()向Java虚拟机返回可用处理器的数目。Process exec(Stringcommand)在单独的

674、进程中执行指定的字符串命令。Process exec(Stringcmds)在单独的进程中执行指定命令和变量。voidexit(intstatus)通过启动虚拟机的关闭序列,终止当前正在运行的Java虚拟机。Java进程longfreeMemory()返回Java虚拟机中的空闲内存量。voidgc()运行垃圾回收器。 staticRuntimegetRuntime()返回与当前Java应用程序相关的运行时对象。voidhalt(intstatus)强行终止目前正在运行的Java虚拟机。voidload(Stringfilename)加载作为动态库的指定文件名。voidloadLibrary(S

675、tringlibname)加载具有指定库名的动态库。Java进程例15-16创建访问网易网站进程。1publicclassStartIE2publicstaticvoidmain(Stringargs)throwsIOException3/设置命令参数设置命令参数4Stringcmd=C:ProgramFiles(x86)InternetExploreriexplore.exe,;5/得到当前运行时得到当前运行时6Runtimert=Runtime.getRuntime();7/在进程中执行指定的字符串命令。在进程中执行指定的字符串命令。8Processp=rt.exec(cmd);910Ja

676、va进程15.8.3Process类Process类是抽象类,由ProcessBuilder和Runtime.exec()方法创建一个本机进程,并返回Process子类的一个实例,该实例可用来控制进程并获取相关信息。Process类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。Java进程Process类的主要方法如下:abstractvoiddestroy()杀掉子进程。abstractintexitValue()返回子进程的出口值。abstractInputStreamgetErrorStream()获得子进程的错误流。abstractI

677、nputStreamgetInputStream()获得子进程的输入流。abstractOutputStreamgetOutputStream()获得子进程的输出流。abstractintwaitFor()导致当前线程等待,如果必要,一直要等到由该Process对象表示的进程已经终止。Java进程图15-6给出父进程得到子进程的输入、输出流的方法。本章结束!第16章网络编程本章内容16.1网络基础知识16.2Java地址类和接口16.3Socket编程16.4UDP编程16.5多播编程16.6广播编程16.1网络基础知识Internet发展至今,它所采纳的网络协议是TCP/IP协议,该协议成为

678、了事实上的网络协议。TCP/IP协议(TransmissionControlProtocol/InternetProtocol,传输控制协议/互联网络协议)是Internet最基本的协议。UDP(UserDatagramProtocol,用户数据报协议)是一种面向无连接的协议,它不要求通讯双方建立连接,就可以直接将数据信息发送出去。1.IP地址在IP协议第4版中,IP地址是一个32位的二进制数,通常被分割为4个8位二进制数(即4个字节)。但为了人们容易理解,IP地址通常用“点分十进制”表示,形如a.b.c.d,其中,a、b、c、d是取值在0255之间的十进制整数。网络基础知识网络基础知识在IP

679、协议第6版中,IP地址是由16个字节构成,并将它分成8段,每段由两个字节构成(即采用4个16进制数表示),而且段之间用冒号分割。网络基础知识2.域名系统域名系统(DomainNameSystem)采用层次结构管理模式,其中的每台域名服务器都存有许多IP地址和域名对应记录。当访问Internet网络上的各种资源时,人们只要输入域名,就可以访问所需资源,根本不需要记住相应的IP地址。例如,3.端口当一台计算机被分配了IP地址后,该计算机便可以提供各种不同的网络服务,比如Web服务、邮件服务、文件服务等。这主要是通过不同端口提供的。网络基础知识端口号可分为3大类:(1)知名端口:从0到1023,紧密

680、绑定一些服务。应应用用服服务务HTTPFTPTELNETDNSTFTPSNMPSMTP知知名名端端口口802123536916125(2)注册端口:从1024到49151。它们松散地绑定了一些服务。也就是说有许多服务绑定在这些端口上,这些端口同样可用于许多其他的服务。(3)动态端口:从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从1024起分配动态端口。网络基础知识4.套接字为了在通信时不发生错乱,IP地址还必须跟端口结合在一起使用。TCP通信需要两个端点进行连接,而每个端点由IP地址和端口决定。而该端点还称为套接字、插口、套接口(Socket)。16.2Java地

681、址类和接口Java语言提供了很多与网络编程有关的地址类和接口,类主要有InetAddress、URL以及URLConnection等,而接口有NetworkInterface。16.2.1InetAddress类Java语言中的InetAddress类主要功能是对IP地址进行封装,该类提供IP地址相关的各种方法,该类无构造方法。而是通过调用相关静态方法进行创建该类对象。InetAddress类的主要方法有:bytegetAddress()返回此InetAddress对象的原始IP地址。StaticInetAddressgetAllByName(StringhostName)在给定主机名的情况下

682、,根据系统上配置的名称服务返回其IP地址所组成的数组。staticInetAddressgetByAddress(byteaddress)在给定原始IP地址的情况下,返回InetAddress对象。Java地址类和接口staticInetAddressgetByAddress(StringhostName,byteaddress)根据提供的主机名和IP地址创建InetAddress。staticInetAddressgetByName(StringhostName)在给定主机名的情况下确定主机的IP地址。StringgetCanonicalHostName()获取此IP地址的完全限定域名。St

683、ringgetHostAddress()返回IP地址字符串(以文本表现形式)。StringgetHostName()获取此IP地址的主机名。staticInetAddressgetLocalHost()返回本地主机。Java地址类和接口-举例例16-1下面是得到网站的IP地址以及本地IP地址。1publicclassTestAddress2publicstaticvoidmain(Stringargs)throwsUnknownHostException3/通过域名得到通过域名得到ip地址对象地址对象4InetAddressremoteIp=InetAddress.getByName();5/

684、返回本地主机返回本地主机6InetAddresslocalIp=InetAddress.getLocalHost();7System.out.println(本地主机本地主机:+localIp);8/获取此获取此IP地址的主机名地址的主机名9System.out.println(ip地址:地址:+remoteIp.getHostAddress();10/获取此获取此IP地址的主机名地址的主机名11System.out.println(主机名字:主机名字:+remoteIp.getHostName();12/得到得到IP地址的完全限定域名地址的完全限定域名13System.out.println

685、(remoteIp.getCanonicalHostName();14try15System.out.println(是否可达是否可达:+remoteIp.isReachable(10000);16catch(Exceptione)17System.out.println(e);1819System.out.println(本地主机本地主机ip地址:地址:+localIp.getLocalHost();20System.out.println(本地主机名字:本地主机名字:+localIp.getLoopbackAddress();212216.2.2URL类在网络服务中,在访问网络中的任何资源

686、时,都需要知道该资源的地址,称之为URL(UniformResourceLocator)。一个完整的URL包括:访问协议类型、主机地址、路径和文件名。URL后面可能还跟一个“片段”,称之为“引用”。该片段由井字符#指示,后面跟有更多的字符。例如,http:/ URL对象访问网址的例子。URLConnection类URLConnection类表示应用程序和URL之间的通信链接。此类的实例可用于读取和写入此URL引用的资源。URLConnection类的主要方法如下:voidaddRequestProperty(Stringkey,Stringvalue)添加由键值对指定的一般请求属性。abstr

687、actvoidconnect()打开到此URL引用的资源的通信链接(如果尚未建立这样的连接)。ObjectgetContent()检索此URL连接的内容。ObjectgetContent(Classclasses)检索此URL连接的内容。intgetContentLength()返回content-length头字段的值。StringgetContentType()返回content-type头字段的值。InputStreamgetInputStream()返回从此打开的连接读取的输入流。OutputStreamgetOutputStream()返回写入到此连接的输出流。StringgetRe

688、questProperty(Stringkey)返回此连接指定的一般请求属性值。URLgetURL()返回此URLConnection的URL字段的值。URLConnection类通常,创建一个到URL的连接需要几个步骤:(1)通过URL调用openConnection方法创建连接对象。(2)操作设置参数和一般请求属性。(3)使用connect方法建立到远程对象的实际连接。(4)远程对象变为可用。远程对象的头字段和内容变为可访问。NetworkInterface接口NetworkInterface接口可以本机在局域网中的IP地址,该接口的主要方法如下:staticNetworkInterfac

689、egetByInetAddress(InetAddressaddr)搜索绑定了指定Internet协议(IP)地址的网络接口的便捷方法。staticNetworkInterfacegetByName(Stringname)搜索具有指定名称的网络接口。StringgetDisplayName()获取此网络接口的显示名称。EnumerationgetInetAddresses()返回一个Enumeration并将所有InetAddress或InetAddress的子集绑定到此网络接口的便捷方法。StringgetName()获取此网络接口的名称。staticEnumerationgetNetwor

690、kInterfaces()返回此机器上的所有接口。NetworkInterface接口例16-3输出本机所有本地网络接口信息。1publicclassLocalIpInfo2publicstaticvoidmain(Stringargs)throwsException3Enumerationsets=NetworkInterface.getNetworkInterfaces();4while(sets.hasMoreElements()/5NetworkInterfacenif=sets.nextElement();/6System.out.println(本地网络接口的显示名称本地网络接口的

691、显示名称:+nif.getDisplayName();7System.out.println(本地网络接口的名称本地网络接口的名称:+nif.getName();891016.3Socket编程网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。一个Socket由一个IP地址和一个端口号唯一确定。1.Socket类该类是实现客户端套接字。Socket类的主要方法如下:Socket()通过系统默认类型的SocketImpl创建未连接套接字。抽象类SocketImpl是实际实现套接字的所有类的通用超类。创建客户端和服务器套接字都可以使用它。Socket(I

692、netAddressaddress,intport)创建一个流套接字并将其连接到指定IP地址的指定端口号。Socket(InetAddressaddress,intport,InetAddresslocalAddr,intlocalPort)创建一个套接字并将其连接到指定远程端口上的指定远程地址。Socket(Stringhost,intport)创建一个流套接字并将其连接到指定主机上的指定端口号。Socket编程Socket(Stringhost,intport,InetAddresslocalAddress,intlocalPort)创建一个套接字并将其连接到指定远程主机上的指定远程端口。

693、voidbind(SocketAddressbindpoint)将套接字绑定到本地地址。voidclose()关闭此套接字。voidconnect(SocketAddressserverAddress)将此套接字连接到服务器。voidconnect(SocketAddressserverAddress,inttimeout)将此套接字连接到具有指定超时值的服务器。InetAddressgetInetAddress()返回套接字连接的地址。InputStreamgetInputStream()返回此套接字的输入流。InetAddressgetLocalAddress()获取套接字绑定的本地地址。

694、intgetLocalPort()返回此套接字绑定到的本地端口。SocketAddressgetLocalSocketAddress()返回此套接字绑定的端点的地址,如果尚未绑定则返回null。OutputStreamgetOutputStream()返回此套接字的输出流。intgetPort()返回此套接字连接到的远程端口。SocketAddressgetRemoteSocketAddress()返回此套接字连接的端点的地址,如果未连接则返回null。Socket编程2.ServerSocket类ServerSocket类实现服务器套接字。服务器套接字等待客户请求通过网络传入。它基于该请求执

695、行某些相应操作,然后还可能向发出该请求客户返回所需要的结果。ServerSocket类的主要方法如下:ServerSocket()创建非绑定服务器套接字。ServerSocket(intport)创建绑定到特定端口的服务器套接字。ServerSocket(intport,intbacklog)利用指定的backlog创建服务器套接字并将其绑定到指定的本地端口号。ServerSocket(intport,intbacklog,InetAddressbindAddr)使用指定的端口port、侦听backlog和要绑定到的本地IP地址创建服务器。Socket编程Socketaccept()侦听并接受

696、到此套接字的连接。voidbind(SocketAddressendpoint)将ServerSocket绑定到特定地址(IP地址和端口号)。voidbind(SocketAddressendpoint,intbacklog)将ServerSocket绑定到特定地址(IP地址和端口号)。voidclose()关闭此套接字。ServerSocketChannelgetChannel()返回与此套接字关联的惟一ServerSocketChannel对象(如果有)。InetAddressgetInetAddress()返回此服务器套接字的本地地址。intgetLocalPort()返回此套接字在其上

697、侦听的端口。SocketAddressgetLocalSocketAddress()返回此套接字绑定的端点的地址,如果尚未绑定则返回null。Socket编程3.服务器与客户端通信过程如图所示。Socket编程对于一个功能齐全的套接字Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:(1)创建连接Socket对象;(2)打开连接到Socket的输入/出流;(3)按照一定的协议对Socket进行读/写操作;(4)关闭Socket。例16-4简单消息对话例子。客户端可以与服务器端相互发送消息。当客户端发送bye信息或者服务器发送down信息,则服务器和客户端交流信息终止。服务器

698、端TalkServer类,客户端TalkClient类16.4UDP编程UDP是一种无连接的协议,每个数据包都包括完整的源(目的)地址,它可以在网络上以随机的路径传到目的地址,因此,UDP协议无法保证该数据包一定能够及时的到达目的地以及数据包内容的正确性。在Java语言中,UDP编程涉及到的类主要有:DatagramSocket类、DatagramPacket类。UDP编程1.DatagramSocket类数据报套接字是数据包收发服务的发送或接收点。每个在数据报套接字上发送或接收的包都是单独编址和路由。从一台计算机发送到另一台计算机的多个包可能选择不同的路由,也可能按不同的顺序到达。在Java

699、语言中,DatagramSocket类表示用来发送和接收数据报包的套接字。在DatagramSocket上总是启用UDP广播发送。为了接收广播包,应该将DatagramSocket绑定到通配符地址。在某些实现中,将DatagramSocket绑定到一个更加具体的地址时广播包也可以被接收。UDP编程DatagramSocket类的主要方法如下:DatagramSocket()构造数据报套接字并将其绑定到本地主机上任何可用的端口。protectedDatagramSocket(DatagramSocketImplimpl)创建带有指定DatagramSocketImpl的未绑定数据报套接字。Dat

700、agramSocket(intport)创建数据报套接字并将其绑定到本地主机上的指定端口。DatagramSocket(intport,InetAddressladdr)创建数据报套接字,将其绑定到指定的本地地址。DatagramSocket(SocketAddressaddress)创建数据报套接字,将其绑定到指定的本地套接字地址。例如:例如:DatagramSocketds=newDatagramSocket(null);ds.bind(newSocketAddress(8888);UDP编程voidbind(SocketAddressaddress)将此DatagramSocket绑定到

701、特定的地址和端口。voidclose()关闭此数据报套接字。voidconnect(InetAddressaddress,intport)将套接字连接到此套接字的远程地址。voidconnect(SocketAddressaddr)将此套接字连接到远程套接字地址(IP地址+端口号)。voiddisconnect()断开套接字的连接。boolean getBroadcast()检测是否启用了SO_BROADCAST。DatagramChannelgetChannel()返回与此数据报套接字关联的惟一DatagramChannel对象(如果有)。InetAddressgetInetAddress(

702、)返回此套接字连接的地址。InetAddressgetLocalAddress()获取套接字绑定的本地地址。intgetLocalPort()返回此套接字绑定的本地主机上的端口号。UDP编程SocketAddressgetLocalSocketAddress()返回此套接字绑定的端点的地址,如果尚未绑定则返回null。intgetPort()返回此套接字的端口。intgetReceiveBufferSize()获取此DatagramSocket的SO_RCVBUF选项的值,该值是平台在DatagramSocket上输入时使用的缓冲区大小。SocketAddressgetRemoteSocket

703、Address()返回此套接字连接的端点的地址,如果未连接则返回null。voidreceive(DatagramPacketp)从此套接字接收数据报包。voidsend(DatagramPacketp)从此套接字发送数据报包。voidsetBroadcast(booleanon)启用/禁用SO_BROADCAST。UDP编程-DatagramPacket类2.DatagramPacket类DatagramPacket(bytebuf,intlength)构造数据报包,用来接收长度为length的数据包。DatagramPacket(bytebuf,intlength,InetAddressa

704、ddress,intport)构造数据报包,用来将长度为length的包发送到指定主机上的指定端口号。DatagramPacket(bytebuf,intoffset,intlength)构造DatagramPacket,用来接收长度为length的包,在缓冲区中指定了偏移量。DatagramPacket(bytebuf,intoffset,intlength,InetAddressaddress,intport)构造数据报包,用来将长度为length偏移量为offset的包发送到指定主机上的指定端口号。DatagramPacket(bytebuf,intoffset,intlength,So

705、cketAddressaddress)构造数据报包,用来将长度为length偏移量为offset的包发送到指定主机上的指定端口号。DatagramPacket(bytebuf,intlength,SocketAddressaddress)构造数据报包,用来将长度为length的包发送到指定主机上的指定端口号。UDP编程-DatagramPacket类InetAddressgetAddress()返回某台机器的IP地址,数据报经此IP地址可被发送或被接收。bytegetData()返回数据缓冲区。intgetLength()返回将要发送或接收到的数据的长度。intgetOffset()返回将要发

706、送或接收到的数据的偏移量。intgetPort()返回某台远程主机的端口号,数据报经此端口可被发送或被接收。SocketAddressgetSocketAddress()获取要将此包发送到的或发出此数据报的远程主机的SocketAddress(通常为IP地址+端口号)。voidsetAddress(InetAddressiaddr)设置要将此数据报发往的那台机器的IP地址。voidsetData(bytebuf)为此包设置数据缓冲区。voidsetData(bytebuf,intoffset,intlength)为此包设置数据缓冲区。voidsetLength(intlength)为此包设置长

707、度。voidsetPort(intiport)设置要将此数据报发往的远程主机上的端口号。voidsetSocketAddress(SocketAddressaddress)设置要将此数据报发往的远程主机的SocketAddress(通常为IP地址+端口号)。UDP编程-DatagramPacket类3.UDP通信过程(客户端1和客户端2之间的UDP通信过程,如图所示)。UDP编程-DatagramPacket类例16-5利用UDP协议进行简单消息对话例子,客户端1和客户端2相互通信。UDPClient1类,UDPClient2类16.5多播编程1.多播概念多播介于单播通信和广播通信之间,它可以

708、将发送者发送的数据包发送给位于分散在不同子网中的一组接收者。而广播则是属于多播中的特例。(广播地址是全1的32位地址,也属于多播地址)2.多播地址在多播编程过程中,编程者需要设置多播地址,多播地址又称组播地址。它是一组主机的标示符。在IPv4中,多播地址范围从224.0.0.0到239.255.255.255。224.0.0.0224.0.0.255为预留的组播地址(永久组地址),地址为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;保留不做分配,其它地址供路由协议使用;224.0.1.0224.0.1.255是公用组播地址,可以用于是公用组播地址,可

709、以用于Internet;224.0.2.0238.255.255.255为用户可用的组播地址(临时组地址),全网为用户可用的组播地址(临时组地址),全网范围内有效;范围内有效;239.0.0.0239.255.255.255为本地管理组播地址,仅在特定的本地范围内为本地管理组播地址,仅在特定的本地范围内有效。有效。多播编程-MulticastSocket类3.MulticastSocket类MulticastSocket类的主要方法如下:MulticastSocket():创建多播套接字。:创建多播套接字。MulticastSocket(intport):创建多播套接字并将其绑定到特定端口。:

710、创建多播套接字并将其绑定到特定端口。MulticastSocket(SocketAddressbindaddr):创建绑定到指定套接字地址的:创建绑定到指定套接字地址的MulticastSocket。MulticastSocket类的其他主要方法如下类的其他主要方法如下InetAddressgetInterface():检索用于多播数据包的网络接口的地址。检索用于多播数据包的网络接口的地址。boolean getLoopbackMode():获取多播数据报的本地回送的设置。获取多播数据报的本地回送的设置。NetworkInterfacegetNetworkInterface():获取多播网络接

711、口集合。获取多播网络接口集合。intgetTimeToLive():获取在套接字上发出的多播数据包的默认生存时间。获取在套接字上发出的多播数据包的默认生存时间。所有的所有的IP包都有一个包都有一个“生存时间生存时间”(time-to-live),又称又称TTL。它是指定一个包到达目的地之前跳过网络的最大次数。单播它是指定一个包到达目的地之前跳过网络的最大次数。单播包通常被允许穿越包通常被允许穿越30个网络,实际上,个网络,实际上,IP包穿过网络的数量包穿过网络的数量通常小于通常小于15个网络。但是许多程序发多播时把个网络。但是许多程序发多播时把TTL设为一个设为一个很低的值,通常为很低的值,通

712、常为0(这样消息不会离开自身的设备)。设(这样消息不会离开自身的设备)。设置为置为1表示只能发到本地网络的计算机,设置为表示只能发到本地网络的计算机,设置为2表示只能表示只能穿过一个路由。穿过一个路由。多播编程-MulticastSocket类voidjoinGroup(InetAddressmcastaddr):加入多播组。voidjoinGroup(SocketAddressmcastaddr,NetworkInterfacenetIf):加入指定接口上的指定多播组。voidleaveGroup(InetAddressmcastaddress):离开多播组。voidleaveGroup(S

713、ocketAddressmcastaddr,NetworkInterfacenetIf):离开指定本地接口上的多播组。voidsetInterface(InetAddressinf):设置多播网络接口,供其行为将受网络接口值影响的方法使用。voidsetLoopbackMode(booleandisable):启用/禁用多播数据报的本地回送。voidsetNetworkInterface(NetworkInterfacenetIf):指定在此套接字上发送的输出多播数据报的网络接口。多播编程-多播通信过程4.多播通信过程(1)信息发送者和信息接收者都创建数据报套接字信息发送者和信息接收者都创建数

714、据报套接字ds并指定端口。并指定端口。(2)信息发送者创建数据报信息发送者创建数据报packet,并将数据报的目的地址设为多播地址,并指并将数据报的目的地址设为多播地址,并指定端口。定端口。(3)信息发送者通过数据套接字发送数据报信息发送者通过数据套接字发送数据报packet,而信息接收者通过数据报套,而信息接收者通过数据报套接字接收数据报接字接收数据报packet。(4)当信息发送完成之后,信息发送者和信息接收者都关闭数据报套接字。当信息发送完成之后,信息发送者和信息接收者都关闭数据报套接字。多播编程例16-6服务器端读取本地数据文件,并对文件(文件名是content.txt)内容进行多播。

715、而客户端接收多播内容。(1)多播服务器线程(MulticastServerThread.java)(2)多播服务器类(MulticastServer.java)1publicclassMulticastServer2publicstaticvoidmain(Stringargs)throwsIOException3newMulticastServerThread().start();45(3)多播客户类(MulticastClient.java)16.6广播编程什么是广播,广播就是一台计算机对某一个网络上的所有计算机发送数据报包。这个网络可能是网络,也可能是子网,还有可能是所有子网。广播有两类

716、:本地广播和定向广播。其中定向广播:将数据报包发送到本网络之外的特定网络的所有主机,然而,由于互联网上的大部分路由器都不转发定向广播消息本地广播:将数据报包发送到本地网络的所有主机,IPv4的本地广播地址为“255.255.255.255”,路由器不会转发此广播;广播编程-广播通信过程广播通信过程,如图所示。广播编程-广播通信过程广播通信过程如下:信息发送者和信息接收者都创建数据报套接字ds并指定端口。信息发送者创建数据报packet,并将数据报的目的地址设为广播地址,并指定端口。信息发送者通过数据套接字发送数据报packet,而信息接收者通过数据报套接字接收数据报packet.当信息发送完成

717、之后,信息发送者和信息接收者都关闭数据报套接字。广播编程-广播通信过程例16-7广播信息例子。1publicclassBroadcastSender2publicstaticvoidmain(Stringargs)3StringaddressStr=255.255.255.255;/本地广播地址字符串本地广播地址字符串4intport=4448;/广播的目的端口广播的目的端口5Stringmessage=广播信息测试广播信息测试test;/要发送的字符串要发送的字符串6try7InetAddressaddress=InetAddress.getByName(addressStr);/广播地址广

718、播地址8DatagramSocketdatagramSocket=newDatagramSocket();/创建数据报套接字创建数据报套接字9DatagramPacketp=newDatagramPacket(message.getBytes(),message.length(),address,port);10datagramSocket.send(p);/发送数据报发送数据报11datagramSocket.close();/关闭数据报套接字关闭数据报套接字1213catch(Exceptione)1415e.printStackTrace();161718广播编程-广播通信过程1publ

719、icclassBroadcastReceiver2publicstaticvoidmain(Stringargs)3intport=4448;/开启监听的端口开启监听的端口4DatagramSocketds=null;5DatagramPacketpacket=null;6try7/数据报套接字绑定指定端口数据报套接字绑定指定端口8ds=newDatagramSocket(port);9bytebuf=newbyte1024;10packet=newDatagramPacket(buf,buf.length);11System.out.println(监听广播端口打开:监听广播端口打开:);1

720、2ds.receive(packet);/接收数据报接收数据报13ds.close();14/将数据报转换成字符串将数据报转换成字符串15Stringmsg=newString(packet.getData(),0,packet.getLength();16System.out.println(收到广播信息长度收到广播信息长度:+packet.getLength()+,广播信息内容广播信息内容:+msg);1718catch(Exceptione)19e.printStackTrace();202122本章结束!第17章数据库编程本章内容17.1数据库基础知识17.2JDBC基础知识17.3访

721、问常用数据库17.4数据操作17.5SQL数据类型与Java数据类型相互转化17.6应用举例17.1数据库基础知识数据库基本概念数据库系统是由数据库DB(Database)、数据库管理系统DBMS(DataBaseManagermemtSystem)、支持数据库运行的软硬环境、数据库应用程序和数据库管理员DBA(DataBaseAdministrator)等组成。数据库DB由一组相互联系的数据文件组成,其中最基本的是包含用户数据的数据文件。数据库管理系统DBMS是专门用于数据库管理的系统软件,提供了应用程序与数据库的接口,允许用户逻辑地访问数据库中的数据,负责逻辑数据与物理地址之间的映射,是控

722、制和管理数据库运行的工具。数据库管理系统可提供数据处理功能包括:数据库定义、数据操纵、数据控制、数据维护功能。 数据库基础知识数据库模型数据库模型主要有层次模型、网状模型以及关系模型。当前主流数据库(例如Oracle、mysql、DB2、SyBase、SQLServer等)模型是关系模型。下面商品销售表是关系表。数据库基础知识-常用的SQL语句结构化查询语言SQL(StructuredQueryLanguage)是一种数据库查询和程序设计语言。1.查询SQL语句查询语句是指查询语句是指SELECT语句,它是用的非常多语句,它是用的非常多SQL语句,其格式如下:语句,其格式如下:SELECTAL

723、L|DISTINCT.AS,.ASFROM!WHEREANDAND|ORAND|ORGROUPBY,HAVINGUNIONALLSELECT命令命令ORDERBYASC|DESC,ASC|DESC数据库基础知识-常用的SQL语句SELECT命令中的函数函数函数功能功能COUNT(*)计算记录个数计算记录个数SUM(FieldName)求字段名求字段名FieldName所指定字段值的总和所指定字段值的总和AVG(FieldName)求字段名求字段名FieldName所指定字段的平均值所指定字段的平均值MAX(FieldName)求字段名求字段名FieldName所指定字段的最大值所指定字段的最大

724、值MIN(FieldName)求字段名求字段名FieldName所指定字段的最小值所指定字段的最小值数据库基础知识-常用的SQL语句查询条件中常用的运算符运算符运算符例子或功能说明例子或功能说明=、=、=、!、!=进价进价30,性别!性别!=“女女”AND、OR、NOT10进价进价and进价进价100与与BETWEEN10AND100等价等价BETWEENAND指定某字段的值在指定的范围内。指定某字段的值在指定的范围内。ISNULL工资现状工资现状ISNULLIN字段内容是结果集合或子查询结果中的内容。字段内容是结果集合或子查询结果中的内容。LIKE对字符型数据进行字符串比较查询,有两个通配符

725、,即对字符型数据进行字符串比较查询,有两个通配符,即下划线下划线“_”表示表示1个字符,百分号个字符,百分号“%”表示若干个字符。表示若干个字符。SOME满足集合中的某一个值,功能与用法等同于满足集合中的某一个值,功能与用法等同于ANY。ALL满足子查询中所有值的记录。满足子查询中所有值的记录。ANY满足子查询中任意一个值的记录。满足子查询中任意一个值的记录。EXISTS测试子查询中查询结果是否为空。若为空,则返回假。测试子查询中查询结果是否为空。若为空,则返回假。数据库基础知识-常用的SQL语句举例:针对商品销售表,给出如下一些SELECT语句。(1)查询全部商品信息。SELECT*FROM

726、商品销售(2)查询所有供货商名单,除去重名。SELECTDISTINCT供货商FROM商品销售(3)统计各供货商商品数量。SELECT供货商,count(*)as商品数量from商品销售GROUPBY供货商(4)查询供货商为广发而且进价在10到100元之间的商品。 SELECT*FROM商品销售where供货商=“广发”and10进价and进价10017.2JDBC基础知识与数据连接相关的接口和类在JDBC中,类主要有DriverManager,接口主要有Driver、Connection等。1.Driver接口每个驱动程序都应该提供一个实现Driver接口的类。在加载某一Driver类时,首

727、先创建自己的实例并向DriverManager注册该实例。Java虚拟机查询并装载驱动程序只需要调用Class类的forName()方法,就能够达到目的。例如,如果你想要使用例如,如果你想要使用JDBC-ODBC桥驱动程序桥驱动程序,则可以用下列代码装载它:则可以用下列代码装载它:Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);与数据连接相关的接口和类2.DriverManager类DriverManager类管理一组JDBC驱动程序的基本服务。作为初始化的一部分,DriverManager类会尝试加载在 “jdbc.drivers”系统属性中引用的

728、驱动程序类。DriverManager类中常用方法如下:staticConnectiongetConnection(Stringurl)试图建立到给定数据库URL的连接。staticConnectiongetConnection(Stringurl,Propertiesinfo)试图建立到给定数据库URL的连接。staticConnectiongetConnection(Stringurl,Stringuser,Stringpassword)试图建立到给定数据库URL的连接。staticDrivergetDriver(Stringurl)试图查找能理解给定URL的驱动程序。staticEnum

729、erationgetDrivers()检索带有当前调用方可以访问的所有当前已加载JDBC驱动程序的Enumeration。staticvoidregisterDriver(Driverdriver)向DriverManager注册指定的驱动程序。与数据连接相关的接口和类例17-1列出当前所有的数据库驱动程序(ListDrivers.java)。1publicclassListDrivers2publicstaticvoidmain(Stringargs)3Enumeratione=DriverManager.getDrivers();4while(e.hasMoreElements()/如果还

730、有驱动程序如果还有驱动程序5Driverd=(Driver)e.nextElement();6System.out.println(d);789与数据连接相关的接口和类Connection接口可以得到与特定数据库的连接(会话)。可以在连接上下文中执行SQL语句并返回结果。Connection接口中的主要方法如下:voidclose()立即释放此Connection对象的数据库和JDBC资源,而不是等待自动释放。voidcommit()使自从上一次提交/回滚以来进行的所有更改成为持久更改,并释放此Connection对象当前保存的所有数据库锁定。StatementcreateStatement(

731、intresultSetType,intresultSetConcurrency,intresultSetHoldability)创建一个Statement对象,该对象将生成具有给定类型、并发性和可保存性的ResultSet对象。boolean getAutoCommit()检索此Connection对象的当前自动提交模式。StringnativeSQL(Stringsql)将给定的SQL语句转换成系统本机SQL语法。与数据连接相关的接口和类CallableStatementprepareCall(Stringsql,intresultSetType,intresultSetConcurren

732、cy,intresultSetHoldability)创建一个CallableStatement对象,该对象将生成具有给定类型和并发性的ResultSet对象。PreparedStatementprepareStatement(Stringsql,intautoGeneratedKeys)创建一个默认PreparedStatement对象,该对象能检索自动生成的键。PreparedStatementprepareStatement(Stringsql,intcolumnIndexes)创建一个能够返回由给定数组指定的自动生成键的默认PreparedStatement对象。PreparedSta

733、tementprepareStatement(Stringsql,intresultSetType,intresultSetConcurrency,intresultSetHoldability)创建一个PreparedStatement对象,该对象将生成具有给定类型、并发性和可保存性的ResultSet对象。PreparedStatementprepareStatement(Stringsql,StringcolumnNames)创建一个能够返回由给定数组指定的自动生成键的默认PreparedStatement对象。与数据连接相关的接口和类void releaseSavepoint(Save

734、pointsavepoint)从当前事务中移除给定Savepoint对象。void rollback()取消在当前事务中进行的所有更改,并释放此Connection对象当前保存的所有数据库锁定。void rollback(Savepointsavepoint)取消设置给定Savepoint对象之后进行的所有更改。void setAutoCommit(booleanautoCommit)将此连接的自动提交模式设置为给定状态。SavepointsetSavepoint(Stringname)在当前事务中创建一个具有给定名称的保存点,并返回表示它的新Savepoint对象。与数据连接相关的接口和类创

735、建数据库连接方法适当的驱动程序类与数据库管理系统DBMS建立一个数据库连接,编程者可以通过下面语句来得到数据连接。Connectioncon=DriverManager.getConnection(url,loginName,password);例如,Stringurl=jdbc:odbc:studentDB;Connectioncon=DriverManager.getConnection(url,sysAdmin,abcde);与数据连接相关的接口和类则JDBCURL的格式表示如下:jdbc:其中subProtocol指示数据库驱动程序类型,而databaseLocator提供网络数据库的

736、位置(包括主机名、端口和数据库名字)。与执行SQL语句相关的接口用于执行静态SQL语句的接口主要:Statement、CallableStatement、reparedStatement,而执行SQL语句可能会产生记录集,就用到接口ResultSet和记录集的ResultSetMetaData。1.Statement接口Statement接口用于执行静态SQL语句并返回它所生成结果的对象。在默认情况下,同一时间每个Statement对象在只能打开一个ResultSet对象。与执行SQL语句相关的接口Statement接口中定义的主要方法如下:voidaddBatch(Stringsql)将给定

737、的SQL命令添加到此Statement对象的当前命令列表中。voidcancel()如果DBMS和驱动程序都支持中止SQL语句,则取消此Statement对象。voidclearBatch()清空此Statement对象的当前SQL命令列表。voidclose()立即释放此Statement对象的数据库和JDBC资源,而不是等待该对象自动关闭时发生此操作。boolean execute(Stringsql)执行给定的SQL语句,该语句可能返回多个结果。boolean execute(Stringsql,intcolumnIndexes)执行给定的SQL语句(该语句可能返回多个结果),并通知驱动

738、程序在给定数组中指示的自动生成的键应该可用于检索。boolean execute(Stringsql,StringcolumnNames)执行给定的SQL语句(该语句可能返回多个结果),并通知驱动程序在给定数组中指示的自动生成的键应该可用于检索。与执行SQL语句相关的接口intexecuteBatch()将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组。ResultSetexecuteQuery(Stringsql)执行给定的SQL语句,该语句返回单个ResultSet对象。intexecuteUpdate(Stringsql)执行给定SQL语句,该语句可能为INS

739、ERT、UPDATE或DELETE语句,或者不返回任何内容的SQL语句。intexecuteUpdate(Stringsql,intcolumnIndexes)执行给定的SQL语句,并通知驱动程序在给定数组中指示的自动生成的键应该可用于检索。intexecuteUpdate(Stringsql,StringcolumnNames)执行给定的SQL语句,并通知驱动程序在给定数组中指示的自动生成的键应该可用于检索。ConnectiongetConnection()检索生成此Statement对象的Connection对象。与执行SQL语句相关的接口2.PreparedStatement接口Prep

740、aredStatement接口的父接口是Statement接口,它表示预编译的SQL语句的对象。SQL语句被预编译并且存储在PreparedStatement对象中。然后可以使用此对象高效地多次执行该语句。PreparedStatement接口中定义的主要方法有:voidaddBatch()将一组参数添加到此PreparedStatement对象的批处理命令中。voidclearParameters()立即清除当前参数值。boolean execute()在此PreparedStatement对象中执行SQL语句,该语句可以是任何种类的SQL语句。ResultSetexecuteQuery()

741、在此PreparedStatement对象中执行SQL查询,并返回该查询生成的ResultSet对象。intexecuteUpdate()在此PreparedStatement对象中执行SQL语句,该语句必须是一个SQLINSERT、UPDATE或DELETE语句;或者是一个什么都不返回的SQL语句,比如DDL语句。与执行SQL语句相关的接口ResultSetMetaDatagetMetaData()检索包含有关ResultSet对象的列消息的ResultSetMetaData对象,ResultSet对象将在执行此PreparedStatement对象时返回。ParameterMetaData

742、getParameterMetaData()检索此PreparedStatement对象的参数的编号、类型和属性。voidsetXXX(intidx,XXXx)将指定参数设置为给定XXX对象。例如,在下列中,假定例如,在下列中,假定con表示一个活动连接:表示一个活动连接:Stringsql=SELECT*FROM商品销售商品销售where?进价进价and进价进价?;PreparedStatementpstmt=con.prepareStatement(sql);pstmt.setInt(1,10);pstmt.setInt(2,200);ResultSetrs=pstmt.executeQu

743、ery();与执行SQL语句相关的接口3.CallableStatement接口该接口的父接口是PreparedStatement,CallableStatement接口的作用是用于执行SQL存储过程。该SQL表达式的内容格式如下:call(?,?,)SQL表达式的参数值可通过PreparedStatement的set()方法进行设置。CallableStatement可以返回一个ResultSet对象或多个ResultSet对象。多个ResultSet对象是使用从Statement中继承的操作处理的。与执行SQL语句相关的接口-ResultSet接口4.ResultSet接口该接口表示数据库

744、结果集的数据表,通常通过执行查询数据库的语句生成。常量值类型常量值类型常量名字及意义常量名字及意义staticint CLOSE_CURSORS_AT_COMMIT该常量指示调用该常量指示调用Cmit方法时应该关闭方法时应该关闭ResultSet对象。对象。staticint CONCUR_READ_ONLY该常量指示不可以更新的该常量指示不可以更新的ResultSet对象的并发模式。对象的并发模式。staticint CONCUR_UPDATABLE该常量指示可以更新的该常量指示可以更新的ResultSet对象的并发模式。对象的并发模式。staticint FETCH_FORWARD该常量指

745、示将按正向(即从第一个到最后一个)处理结果集中的行。该常量指示将按正向(即从第一个到最后一个)处理结果集中的行。staticint FETCH_REVERSE该常量指示将按反向(即从最后一个到第一个)处理结果集中的行处理。该常量指示将按反向(即从最后一个到第一个)处理结果集中的行处理。staticint FETCH_UNKNOWN该常量指示结果集中的行的处理顺序未知。该常量指示结果集中的行的处理顺序未知。staticint HOLD_CURSORS_OVER_COMMIT该常量指示调用该常量指示调用Cmit方法时不应关闭方法时不应关闭ResultSet对对象。象。staticint TYPE_

746、FORWARD_ONLY该常量指示指针只能向前移动的该常量指示指针只能向前移动的ResultSet对象的类型。对象的类型。staticint TYPE_SCROLL_INSENSITIVE该常量指示可滚动但通常不受其他更改影响该常量指示可滚动但通常不受其他更改影响ResultSet对象的类型。对象的类型。staticint TYPE_SCROLL_SENSITIVE该常量指示可滚动并且通常受其他更改影响的该常量指示可滚动并且通常受其他更改影响的ResultSet对象的类型。对象的类型。与执行SQL语句相关的接口-ResultSet接口默认的ResultSet对象不可更新,仅有一个向前移动的指针

747、。此外,还可以生成可滚动并且可更新的ResultSet对象。例如:Statementstmt=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);ResultSetrs=stmt.executeQuery(“SELECT*FROM商品销售”);与执行SQL语句相关的接口-ResultSet接口ResultSet接口的主要方法如下:voidafterLast()将指针移动到该ResultSet对象的末尾,正好位于最后一行之后。voidbeforeFirst()将指针移动到此Result

748、Set对象的开头,正好位于第一行之前。boolean next()将指针从当前位置下移一行。boolean previous()将指针移动到此ResultSet对象的上一行。boolean absolute(introw)将指针移动到该ResultSet对象的给定行编号。boolean first()将指针移动到此ResultSet对象的第一行。voidcancelRowUpdates()取消对ResultSet对象中的当前行所作的更新。voidclose()立即释放此ResultSet对象的数据库和JDBC资源,而不是等待该对象自动关闭时发生此操作。与执行SQL语句相关的接口-ResultS

749、et接口voiddeleteRow()从ResultSet对象和底层数据库中删除当前行。intfindColumn(StringcolumnName)将给定的ResultSet列名称映射到其ResultSet列索引。XXXgetXXX(intcolumnIndex)以XXX的形式检索此ResultSet对象的当前行中指定列的值。XXXgetXXX(StringcolumnName)以XXX的形式检索此ResultSet对象的当前行中指定列的值。voidupdateXXX(StringcolumnName,XXXx)用XXX值更新指定列。voidupdateXXX(intcolumnIndex,

750、XXXx)用XXX值更新指定列.与执行SQL语句相关的接口-ResultSet接口StringgetCursorName()检索此ResultSet对象使用的SQL指针的名称。intgetRow()检索当前行编号。ResultSetMetaDatagetMetaData()检索此ResultSet对象的列的编号、类型和属性。StatementgetStatement()检索生成此ResultSet对象的Statement对象。intgetType()检索此ResultSet对象的类型。voidinsertRow()将插入行的内容插入到此ResultSet对象和数据库中。voidmoveToCu

751、rrentRow()将指针移动到记住的指针位置,通常为当前行。voidmoveToInsertRow()将指针移动到插入行。voidrefreshRow()用数据库中的最近值刷新当前行。boolean relative(introws)按相对行数(或正或负)移动指针。boolean rowDeleted()检索是否已删除某行。boolean rowInserted()检索当前行是否已有插入。boolean rowUpdated()检索是否已更新当前行。与执行SQL语句相关的接口5.ResultSetMetaData接口ResultSetMetaData接口主要作用是获取关于ResultSet对

752、象中列的类型和属性信息。ResultSetMetaData接口的主要方法有:StringgetCatalogName(intcolNo)获取指定列的表目录名称。StringgetcolNoClassName(intcolNo)如果调用方法ResultSet.getObject从列中检索值,则返回构造其实例的Java类的完全限定名称。intgetcolNoCount()返回此ResultSet对象中的列数。intgetcolNoDisplaySize(intcolNo)指示指定列的最大标准宽度,以字符为单位。StringgetcolNoLabel(intcolNo)获取用于打印输出和显示的指定列

753、的建议标题。StringgetcolNoName(intcolNo)获取指定列的名称。intgetcolNoType(intcolNo)检索指定列的SQL类型。与执行SQL语句相关的接口StringgetcolNoTypeName(intcolNo)检索指定列的数据库特定的类型名称。intgetPrecision(intcolNo)获取指定列的小数位数。intgetScale(intcolNo)获取指定列的小数点右边的位数。StringgetSchemaName(intcolNo)获取指定列的表模式。StringgetTableName(intcolNo)获取指定列的名称。boolean is

754、AutoIncrement(intcolNo)指示是否自动为指定列进行编号,这样这些列仍然是只读的。intisNullable(intcolNo)指示指定列中的值是否可以为null。与执行SQL语句相关的接口例17-3在类DBCon中定义输出记录集的表头方法。1publicvoidprintTableHeader(ResultSetrs)throwsException2if(rs!=null)3/打印表头打印表头4ResultSetMetaDatarsMD;5rsMD=rs.getMetaData();/6inti,count=rsMD.getColumnCount();7for(i=1;i=

755、count;i+)8Stringstr;9str=rsMD.getColumnName(i);/得到表头的第得到表头的第i列字段名列字段名10System.out.print(str+t);1112System.out.println();1314与执行SQL语句相关的接口例17-4在类DBCon中定义输出记录集方法。1publicvoidprintRecords(ResultSetrs)throwsException2/打印表头打印表头3this.printTableHeader(rs);4intcount,i;5ResultSetMetaDatarsMD;6rsMD=rs.getMetaD

756、ata();7count=rsMD.getColumnCount();/得到记录集的列数量得到记录集的列数量8if(rs!=null)9/输出记录集中的数据输出记录集中的数据10while(rs.next()11for(i=1;i0)/78for(inti=1;i=numberOfColumns;i+)9Objectob;10ob=rs.getObject(i);/当前记录的第当前记录的第i个字段个字段11if(ob!=null)12System.out.print(ob+t);13else14System.out.print(tt);1516System.out.println(t);/换行

757、换行171817.3访问常用数据库访问Access数据库17.3访问常用数据库访问mysql数据库。MySQL是功能强大又小巧的数据库。官网(http:/ ;(3) 统计各供货商商品数量统计各供货商商品数量;(4) ;(4) 查询供货商为广发而且进价在查询供货商为广发而且进价在2 2到到2020元之间元之间的商品;(的商品;(5 5)查询出供货商为)查询出供货商为“广发广发”或或“扬子江行扬子江行”的品名、进价的品名、进价以及零售单价以及零售单价;(6);(6)查询出所有以查询出所有以“广广”开头的供货商名单。开头的供货商名单。( (QueryTest1.java) )更新记录集操作1.通过R

758、esultSet对象更新当前行中的列值。在可滚动的ResultSet对象中,可以向前或向后移动指针,将其置于绝对位置或相对于当前行的位置。然后使用方法updateRow更新用于派生rs的数据源表。例17-11在DBCon类中定义executeQueryWithUpdate(Stringsql)方法,该方法返回可更新的ResultSet对象。 更新记录集操作1publicResultSetexecuteQueryWithUpdate(Stringsql)2ResultSetrs=null;3try4con=this.getConnection();5Statementst;6st=con.cre

759、ateStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);7rs=statement.executeQuery(sql);89catch(Exceptione)10System.out.println(e);1112returnrs;1314更新记录集操作例17-12针对access库文件xs.mdb,创建ODBC数据源,该数据源名称是ShangPin,创建UpdateRecord1.java文件,修改商品销售指定编号的记录,并移动记录指针位置并显示当前记录指针位置上的记录值。更新记录集操作有时需要直接

760、操作数据库中的表格,完成此操作的最简单方法是执行update语句。例例17-13在在DBCon类中定义更新操作方法类中定义更新操作方法executeUpdate(Stringsql)如下:如下:1publicvoidexecuteUpdate(Stringsql)throwsSQLException2Statementstmt;3stmt=con.createStatement();4stmt.executeUpdate(sql);5stmt.close();6更新记录集操作例17-14对于mysql的数据库mydb中的商品销售表进行修改操作。17.4.3插入记录操作在插入记录的方法主要有:通

761、过记录集ResultSet对象完成插入操作和使用insertSQL语句两种。1.通过记录集ResultSet对象完成插入操作可更新的ResultSet对象具有一个与其关联的特殊行,该行用作构建要插入的行的暂存区域,可以通过moveToInsertRow()方法移动到该行。向ResultSet对象中将记录值插入的思路是:首先,将记录指针移动到插入行(暂存区域);然后,将更新该插入行的各字段值;最后,使用insertRow方法将其插入到rs和数据源表中;插入记录操作插入记录操作例17-15访问mysql数据库系统,要求向mydb数据库中的student表插入记录。Student表的数据结构和数据分

762、别如图所示。(InsertRecord1.java)插入记录操作2.通过SQL语句插入数据有时可以直接操作数据库中的表格,完成此操作的最简单方法是执行SQLinsert语句。例17-16访问mysql数据库系统,要求向mydb数据库中的商品销售表插入记录。(InsertRecord2.java)17.4.4删除记录操作删除记录集中的记录有两种方法: (1)通过SQL的删除语句删除记录;(2)从ResultSet对象和底层数据库中删除记录行。1.通过调用SQL的删除语句删除记录。例17-16访问mysql数据库系统,对数据库mydb的中student表进行删除操作。(DeleteRecord1.

763、java)删除记录操作2.通过ResultSet对象删除记录行通过此方法删除记录行需要注意的是:(1)ResultSet对象必须支持可以更新和游标可移动。(2)ResultSet对象当前记录指针必须指向某条记录上,否则就会出错。(3)该记录集只能由从单个表查询得到。例17-17访问mysql数据库系统,对数据库mydb中student表进行删除记录操作。注意,此处利用ResultSet对象进行删除操作。(DeleteRecord2.java)17.4.5JDBC事务事务是为解决数据安全操作提出的,控制事务实际上就是控制数据的安全访问。JDBC事务Java事务的类型有三种:JDBC事务、JTA(

764、JavaTransactionAPI)事务、容器事务。其中JTA是一种高层的,与实现无关的,与协议无关的API,应用程序和应用服务器可以使用JTA来访问事务。JTA允许应用程序执行分布式事务处理在两个或多个网络计算机资源上访问并且更新数据,这些数据可以分布在多个数据库上。JDBC驱动程序的JTA支持极大地增强了数据访问能力。而容器事务主要是J2EE应用服务器提供的,容器事务大多是基于JTA完成。这是一个基于JNDI的,相当复杂的API实现。JDBC事务是用Connection对象来控制。JDBCConnection类提供了两种事务模式:自动提交和手动提交。JDBC事务方法一:不设置回滚点方法。

765、(Transfer1.java)方法二:设置回滚点。(Transfer2.java)JDBC事务进行控制事务操作过程如下:(1)调用Connection类的publicvoidsetAutoCommit(false),将此连接的自动提交模式设置为手动模式。(2)通过预处理语句执行更新等操作;(3)执行提交操作,即调用Connection类的publicvoidcommit()方法即可。在执行这步操作过程中,如果发生了异常,则可以调用Connection类的publicvoidrollback()方法,执行回滚事务操作。JDBC事务当然,有时候可能需要手动设置事务的回滚点,在JDBC事务操作中,

766、可以使用如下语句设置事务回滚点:Savepointsp=con.setSavepoint();/con是数据连接对象然后调用publicvoidrollback(sp)方法回滚,其中sp就是上面定义的回滚点。最后,还要通知数据库提交事务,即再次调用Connection类的publicvoidcommit()方法。例17-18假定上述Clients表是一个access2010的数据库clients.accdb中的表,要进行一笔转账业务(即陆展元向李莫愁转2000元),假设已经建立数据源clients,如图17-24所示。JDBC事务17.5SQL数据类型与Java数据类型相互转化17.5SQL数

767、据类型与Java数据类型相互转化SQL数据类型到Java数据类型映射SQL数据类型数据类型JAVA数据类型数据类型CHARStringVARCHARStringLONGVARCHARStringNUMERICjava.math.BigDecimalDECIMALjava.math.BigDecimalBITBooleanTINYINTByteSMALLINTShortINTEGERIntBIGINTLongREALFloatFLOATDoubleDOUBLEDoubleBINARYbyteVARBINARYbyteLONGVARBINARYbyteDATEjava.sql.DateTIMEja

768、va.sql.TimeTIMESTAMPjava.sql.Timestamp17.5SQL数据类型与Java数据类型相互转化SQL数据类型到Java数据类型映射 JAVA数据数据类类型型SQL数据数据类类型型StringVARCHAR or LONGVARCHARjava.math.BigDecimalNUMERICBooleanBITByteTINYINTShortSMALLINTIntINTEGERLongBIGINTFloatREALDoubleDOUBLEbyteVARBINARY or LONGVARBINARYjava.sql.DateDATE java.sql.TimeTIMEj

769、ava.sql.TimestampTIMESTAMP17.6应用举例题目要求:设计教师选课登录窗体程序,点击登录按钮后,如果密码正确,则进入到选择任课窗体程序。注意:任何教师可以添加自己在指定学期任教的课程。注意:(1)任意两条记录的教师编号、课程编号、以及选课时段编号不同;(2)要保证教师编号、课程编号都必须存在。应用举例17.6.1例题的数据表及其表结构teacher表表应用举例course表表student表表应用举例teachCourse表表terms表表应用举例17.6.2程序界面设计应用举例17.6.3在DBCon类中新创建的方法(1)listDataOnTableFromRS()方法,其功能:将记录集显示在指定的表格控件上。17.6.4登录类teacherLogin的设计17.6.5类teacherSelectCourse本章结束!

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号