Java程序设计实用教程第2版PPT精品课程课件全册课件汇总

上传人:m**** 文档编号:568802519 上传时间:2024-07-26 格式:PPT 页数:644 大小:8.75MB
返回 下载 相关 举报
Java程序设计实用教程第2版PPT精品课程课件全册课件汇总_第1页
第1页 / 共644页
Java程序设计实用教程第2版PPT精品课程课件全册课件汇总_第2页
第2页 / 共644页
Java程序设计实用教程第2版PPT精品课程课件全册课件汇总_第3页
第3页 / 共644页
Java程序设计实用教程第2版PPT精品课程课件全册课件汇总_第4页
第4页 / 共644页
Java程序设计实用教程第2版PPT精品课程课件全册课件汇总_第5页
第5页 / 共644页
点击查看更多>>
资源描述

《Java程序设计实用教程第2版PPT精品课程课件全册课件汇总》由会员分享,可在线阅读,更多相关《Java程序设计实用教程第2版PPT精品课程课件全册课件汇总(644页珍藏版)》请在金锄头文库上搜索。

1、授课人:XXXXPPT内容可自行编辑Java-Java-程序设计程序设计- -实用实用教程教程( (第第2 2版版) )精品课程精品课程课件制作人:XXXJSP程序设计教程n第1章Java程序设计语言概述n第2章JAVA语言的基本语法n第3章程序流程控制语句n第4章面向对象基础n第5章集合类n第6章Java输入与输出(I/O)n第7章多线程与异常处理n第8章Swing程序设计n第9章Applet程序设计n第10章网络程序设计n第11章JDBC数据库编程n第12章JavaWeb程序设计课件制作人:XXX第1章Java程序设计语言概述1.1Java简介1.2Java语言诞生背景1.3Java语言的

2、特点1.4安装Java程序开发工具1.5JDK6.0的新特性1.6Java程序开发过程1.7开发工具Eclipse课件制作人:XXX1.1Java简介Java语言得名于印度尼西亚一个盛产咖啡的岛屿,中文名叫爪哇,其寓意是为世人端上一杯热咖啡。正如认识一个新事物一样,学习一门语言应该是从整体到细节,再从细节到整体的过程。学习Java语言也是一样,首先需要对其有一个整体的了解,然后再慢慢的学习具体内容,最后达到完全掌握Java语言的目的。目前,Java主要有3个独立的版本。nJavaSEnJavaEEnJavaME课件制作人:XXXJavaSEJavaSE是Java语言的标准版本,包含Java基础

3、类库和语法。它用于开发具有丰富的GUI(图形用户界面)、复杂逻辑和高性能的桌面应用程序。课件制作人:XXXJavaEEJavaEE用于编写企业级应用程序。它是一个标准的多层体系结构,可以将企业级应用程序划分为客户层、表示层、业务层和数据层,主要用于开发和部署分布式、基于组件、安全可靠、可伸缩和易于管理的企业级应用程序。课件制作人:XXXJavaMEJ2ME主要用于开发具有有限的连接、内存和用户界面能力的设备应用程序。例如移动电话(手机)、PDA(电子商务)、能够接入电缆服务的机顶盒或者各种终端和其他消费电子产品。课件制作人:XXX1.2Java语言诞生背景Java语言是Sun公司于1990年开

4、发的,当时Green项目小组的研究人员正在致力于为未来的智能设备开发出一种新的编程语言,由于该小组的成员JamesGosling对C+的执行过程中的表现非常不满,于是把自己封闭在办公室里编写了一种新的语言,并将其命名为Oak。课件制作人:XXXOakOak就是Java语言的前身,这个名称源于Gosling办公室的窗外正好有一棵橡树(Oak)。这时的Oak已经具备安全性、网络通信、面向对象、GarbageCollected、多线程等特性,是一款相当优秀的程序语言。后来,由于去注册Oak商标时,发现它已经被另一家公司注册,所以不得不改名。要取什么名字呢,工程师们边喝咖啡边讨论着,看看手上的咖啡,再

5、想到印度尼西亚有一个重要的盛产咖啡的岛屿,中文名叫爪哇,于是将其改名为Java。课件制作人:XXXHotJava随着Internet的迅速发展,Web的应用日益广泛,Java语言也得到了迅速发展。1994年,Gosling用Java开发了一个实时性较高、可靠、安全、有交互功能的新型Web浏览器,它不依赖于任何硬件平台和软件平台。这种浏览器名称为HotJava,并于1995年同Java语言一起,正式在业界对外发表,引起了巨大的轰动,Java的地位随之而得到肯定。此后的发展非常迅速。课件制作人:XXXJava语言的特点Java语言适用于Internet环境,是一种被广泛使用的网络编程语言,它具有简

6、单、面向对象、可移植、分布性、解释器通用性、稳健、多线程、安全及高性能等语言特性。另外Java语言还提供了丰富的类库,方便用户进行自定义操作。下面将对Java语言的特点进行具体介绍。课件制作人:XXX1.3.1简单Java语言的语法规则和C+类似。它通过提供最基本的方法完成指定的任务。但Java语言对C+进行了简化和提高。例如,指针和多重继承通常使程序变得复杂,Java用接口取代了多重继承,并取消了指针。Java语言还通过实现自动垃圾收集大大简化了程序设计人员的内存管理工作。课件制作人:XXX1.3.2面向对象Java语言以面向对象为基础。在Java语言中,不能在类外面定义单独的数据和函数,所

7、有对象都要派生于同一个基类,并共享它所有功能,也就是说,Java语言最外部的数据类型是对象,所有的元素都要通过类和对象来访问。课件制作人:XXX1.3.3可移植性Java程序具有与体系结构无关的特性。这一特征使Java程序可以方便地移植到网络的不同机器。同时,Java的类库中也实现了针对不同平台的接口,使这些类库可以移植。课件制作人:XXX1.3.4分布性Java语言从诞生就和网络紧密地联系在一起。在Java中还内置了TCP/IP、HTTP和FTP等协议类库。因此,Java应用程序可以通过URL地址打开访问网络上的对象,访问方式与访问本地文件系统几乎完全相同。课件制作人:XXX1.3.5解释器

8、通用性运行Java程序需要解释器。Java解释器能直接对Java字节码进行解释执行。字节代码独立于机器,它本身携带了许多编译时信息,使得连接过程更加简单,因此可以在任何有Java解释器的机器上运行。课件制作人:XXX1.3.6健壮Java能够检查程序在编译和运行时的错误。类型检查能帮助用户检查出许多在开发早期出现的错误。同时很多集成开发工具(IDE)的出现使编译和运行Java程序更加容易,并且很多集成开发工具(如Eclipse)都是免费的。课件制作人:XXX1.3.7多线程多线程是程序同时执行多个任务的一种功能。多线程机制能够使应用程序并行执行多项任务,而且同步机制保证了各线程对共享数据的正确

9、操作。使用多线程,程序设计人员可以用不同的线程完成特定的行为,使程序具有更好的交互能力和实时运行能力。课件制作人:XXX1.3.8高性能由于Java程序是可解释的,字节码不是直接由系统执行,而是在解释器中运行,所以它的速度比多数交互式应用程序提高了很多。课件制作人:XXX1.4安装Java程序开发工具下载JDK安装JDK配置和测试JDK课件制作人:XXX1.5 JDK 6.0的新特性刚刚发布的Java Standard Edition 6(Java SE 6,也被称为Mustang)包括了许多新特性。例如全新的桌面新特性:n新增的系统托盘SystemTray类n调用桌面系统功能的Desktop

10、类n表格的排序和过滤功能这些新特性使Java SE 6有希望成为Java桌面应用开发的一次革命。课件制作人:XXX其他新特性Java平台除了命名方式上的改变(去掉了原名称的数字2)和上述特性之外,JDK6还包含了很多值得探索的新特性。例如:nJava对象与XML之间的映射n使用CompilerAPI动态编译n轻量级HttpServern但是,在探索这些新特性之前,必须将基础打好。课件制作人:XXX1.6Java程序开发过程在还没有正式开发Java程序前,首先需要对Java程序的开发过程有所了解。开发Java程序总体上可以分为3个步骤:n编写Java源文件n编译Java源文件n运行Java程序课

11、件制作人:XXX编写Java源文件Java源文件是一种纯文本文件,它可以使用任何文本编辑器进行编辑,其扩展名为.java。例如,可以使用Windows的记事本编写一个名称为OneJavaApp.java的Java源文件。课件制作人:XXX编译Java源文件编译Java源文件,也就是将Java源文件编译(Compile)成Java类文件(扩展名为.class)。例如,将OneJavaApp.java文件编译成OneJavaApp.class类文件使用如下命令:注:编译Java的原文件,需要指定文件扩展名。javacOneJavaApp.java课件制作人:XXX运行Java程序Java程序可以分

12、为JavaApplication(Java应用程序)和JavaApplet(Java小应用程序)。其中,JavaApplication必须通过Java解释器(java.exe)来解释执行其字节码文件,即类文件,JavaApplet需要使用支持它的浏览器(如NetscapeNavigator或IE等)运行。运行Java应用程序的命令如下:注:运行Java的类文件,不需要指定文件扩展名。javaOneJavaApp课件制作人:XXX1.7开发工具Eclipse1.7.1Eclipse简介(一)Eclipse是基于Java的,开放源码的、可扩展的应用开发平台,它为编程人员提供了一流的Java集成开发

13、环境(IntegratedDevelopmentEnvironment,IDE)。是一个可以用于构建集成Web和应用程序的开发工具平台,其本身并不会提供大量的功能,而是通过插件来实现程序的快速开发功能。课件制作人:XXX1.7.1Eclipse简介(二)Eclipse是一个成熟的可扩展的体系结构。它为创建可扩展的开发环境提供了一个平台。这个平台允许任何人构建与环境或其他工具无缝集成的工具,而工具与Eclipse无缝集成的关键是插件。Eclipse还包括插件开发环境(PDE),PDE主要针对那些希望扩展Eclipse的编程人员而设定的。这也正是Eclipse最具魅力的地方。通过不断的集成各种插件

14、,Eclipse的功能也在不断的扩展,以便支持各种不同的应用。虽然Eclipse是针对Java语言而设计开发的,但是它的用途并不局限于Java语言,通过安装不同的插件Eclipse还可以支持诸如C/C+、PHP、COBOL等编程语言。课件制作人:XXX1.7.1Eclipse简介(三)Eclipse利用Java语言写成,所以Eclipse可以支持跨平台操作,但是需要SWT(StandardWidgetToolkit)的支持,不过这已经不是什么大问题了,因为SWT已经被移植到许多常见的平台上,例如Windows、Linux、Solaris等多个操作系统,甚至可以应用到手机或者PDA程序开发中。J

15、SP程序设计教程课件 制作人:XXXJava实用教程第2章Java语言的基本语法课件制作人:XXX第2章JSP开发基础2.1标识符和关键字2.2常量与变量2.3数据类型2.4运算符2.5字符串2.6数组课件制作人:XXX2.1标识符和关键字Java语言中的类名、对象名、方法名、常量名和变量名统称为标识符。标识符由程序员定义,可以由字母、数字、下划线(_)和($)符号组成,但是标识符的第一个字符不允许为数字,只允许为字母、下划线(_)或($)符号。在Java语言中还定义了一些专有词汇,统称为关键字,例如public、class、int等,它们都具有一种特定的含义,只能用于特定的位置,不能作为标识

16、符使用。课件制作人:XXXJava关键字abstractconstfinallyintpublicthisbooleancontinuefloatinterfacereturnthrowbreakdefaultforlongshortthrowsbytedogotonativestatictransientcasedoubleifnewstrictfptrycatchelseimplements packagesupervoidcharextendsimportprivateswitchvolatileclassfinalinstanceofprotectedsynchronizedwhile

17、在定义标识符时,不允许定义为表中列出的任一关键字课件制作人:XXXJava标识符命名规则为了提高程序的可读性,在定义标识符时,要尽量遵循“见其名知其意“的原则。Java标识符的具体命名规则如下:n一个标识符可以由几个单词连接而成,以表明它的意思。n对于类名,每个单词的首字母都要大写,其他字母则小写,例如RecordInfo。n对于方法名和变量名,与类名有些相似,除了第一个单词的首字母小写外,其他单词的首字母都要大写,例如getRecordName() 。课件制作人:XXXJava标识符命名规则n对于常量名,每个单词的每个字母都要大写,如果由多个单词组成,通常情况下单词之间用下划线(_)分隔,例

18、如MAX_VALUE。n对于包名,每个单词的每个字母都要小写,例如com.frame。 注意:Java语言是区分字母大小写的,即Java不等于java课件制作人:XXX2.2常量与变量常量和变量在程序代码中随处可见,下面就具体讲解常量和变量的概念及使用要点,从而达到区别常量和变量的目的。课件制作人:XXX2.2.1常量的概念及使用要点所谓常量,就是值永远不允许被改变的量。如果要声明一个常量,就必须用关键字final修饰,声明常量的具体方式如下:final常量类型常量标识符;例如:final intYOUTH_AGE;/声明一个int型常量final floatPIE;/声明一个float型常量

19、注意:注意:按照Java命名规则,常量标识符所有的字符都要大写,各个单词之间用下划线_分隔课件制作人:XXX常量在声明常量时,通常情况下立即为其赋值,即立即对常量进行初始化即立即对常量进行初始化,声明并初始化常量的具体方式如下:final常量类型常量标识符=常量值;例如:finalintYOUTH_AGE=18;/声明int型常量,初始化为18finalfloatPIE=3.14F;/声明float型常量,初始化为3.14说明:说明:为float型常量赋值时,需要在数值的后面加上一个字母“F”或“f”。课件制作人:XXX常量声明多个同一类型的常量,可以采用下面的形式:final常量类型常量1=

20、常量值1,常量2=常量值2,;例如:finalintNUM1 = 14, NUM2 = 25, NUM3 = 36;注意:如果在声明常量时已经对其进行了初始化,则常量的值不允许再被修改课件制作人:XXX2.2.2变量的概念及使用要点所谓变量,就是值可以被改变的量。声明变量的具体方式如下:变量类型变量标识符;例如:注意:定义变量名时,按照Java的命名规则,第一个单词的首字母小写,其他单词的首字母大写,例如“partyMemberAge”。Stringname;/声明String型变量intpartyMemberAge;/声明int型变量课件制作人:XXX变量在声明变量时,可以立即为其赋值,即立

21、即对变量进行初始化,具体语法如下:变量类型变量标识符=变量值;例如:intpartyMemberAge=26;/声明一个int型变量floatmoney=3150;/声明float类型变量课件制作人:XXX同类型变量如果需要声明多个同一类型的变量,也可以采用下面的形式:变量类型变量1,变量2,变量3;变量类型变量4=变量值4,变量5=变量值5,变量6=变量值6;例如:说明:变量区别于常量,它的值允许被改变。intA,B,C;/声明3个int型变量intD=4,E=5,F=6;/声明并分别初始化3个int型变量课件制作人:XXX2.3数据类型Java语言中的数据类型划分为两大类,分别是基本数据类

22、型和引用数据类型。其中基本数据类型由Java语言定义,不可以再进行划分。基本数据类型的数据占用内存的大小固定,在内存中存入的是数值本身引用数据类型在内存中存入的是引用数据的存放地址,并不是数据本身。Java语言中的数据类型分类情况如下图所示:课件制作人:XXX数据类型课件制作人:XXX2.3.1基本数据类型基本数据类型分为:n整数型n浮点数型n字符型n逻辑型(布尔型)它们分别用来存储整数、小数、字符和布尔值,下面将依次讲解这4个基本数据类型的特征及使用方法。课件制作人:XXX整数型声明为整数型的常量或变量用来存储整数,整数型包括:n字节型(byte)n短整型(short)n整型(int)n长整

23、型(long)这4个数据类型的区别是它们在内存中所占用的字节数不同,因此,它们所能够存储的整数的取值范围也不同。课件制作人:XXX整数占用内存大小以及取值范围数据类型关键字内存字节取值范围字节型byte1个字节-128127短整型short2个字节-3276832767整型int4个字节-21474836482147483647长整型long8个字节-92233720368547758089223372036854775807课件制作人:XXX长整型数值在为long型常量或变量赋值时,需要在所赋值的后面加上一个字母“L”(或“l”),说明所赋的值为long型。如果所赋的值未超出int型的取值范

24、围,也可以省略字母“L”(或“l”)。例如下面的代码均是正确的。longla=9876543234L;/超出了int取值范围,必须加“L”longlb=98765432L;/未超出int取值范围,也可以加“L”longlc=98765432;/未超出int取值范围,可以省略“L”课件制作人:XXX浮点数声明为浮点数型的常量或变量用来存储小数,浮点数包括单精度型(float)和双精度(double)两个基本数据类型,这两个数据类型的区别是它们在内存中所占用的字节数不同,因此,它们所能够存储的整数的取值范围也不同数据类型数据类型关键字关键字占用内存字节数占用内存字节数取值范围取值范围单精度型flo

25、at4字节1.4E-453.4028235E38双精度型double8字节4.9E-3241.7976931348623157E308课件制作人:XXXfloat型数值在为float型常量或变量赋值时,需要在所赋值的后面加上一个字母“F”(或“f”),说明所赋的值为float型。如果所赋的值为整数,并且未超出int型的取值范围,也可以省略字母“F”(或“f”)。例如下面的代码均是正确的。floatfa=9412.75F;/赋值为小数,必须“F”floatfb=9876543210F;/赋值超出int取值范围,必须“F”floatfc=9412F;/未超出int取值范围,可以“F”floatfd

26、=9412;/也可以省略“F”课件制作人:XXXdouble型数值在为double型常量或变量赋值时,需要在所赋值的后面加上一个字母“D”(或“d”),说明所赋的值为double型。如果所赋的值为小数,或者所赋的值为整数,并且未超出int型的取值范围,也可以省略字母“D”(或“d”)。例如下面的代码均是正确的。doubleda=9412.75D;/所赋值为小数,可以加上“D”doubledb=9412.75;/所赋值为小数,也可以省略“D”doubledc=9412D;/未超出int取值范围,可以加上“D”doubledd=9412;/未超出int取值范围,可以省略“D”doublede=98

27、76543210D;/超出int取值范围,必须加上“D课件制作人:XXX字符型声明为字符型的常量或变量用来存储单个字符,它占用内存的2个字节来存储,字符型利用关键字“char”进行声明。Java中的字符通过Unicode字符编码,以二进制的形式存储到计算机中,计算机可通过数据类型判断要输出的是一个字符还是一个整数。Unicode编码采用无符号编码,一共可存储65536个字符,所以Java中的字符几乎可以处理所有国家的语言文字。课件制作人:XXX字符型数值在为char型常量或变量赋值时,无论值是一个英文字母,或者是一个符号,还是一个汉字,必须将所赋的值放在英文状态下的一对单引号中。例如下面的代码

28、分别将字母“M”、符号“*”和汉字“男”赋值给char型变量ca、cb和cc。charca=M;/将大写字母“M”赋值给char型变量charcb=*;/将符号“*”赋值给char型变量charcc=男;/将汉字“男”赋值给char型变量课件制作人:XXX逻辑型声明为逻辑型的常量或变量用来存储逻辑值,逻辑值只有true和false,分别用来代表逻辑判断中的“真”和“假”,逻辑型利用关键字“boolean”进行声明。例如下面的代码分别将true和false赋值给变量ba和bb。booleanba=true;/将true赋值给变量babooleanbb=false;/将false赋值给变量bb课件

29、制作人:XXX逻辑型也可以将逻辑表达式赋值给boolean型变量,例如下面的代码分别将逻辑表达式“68”赋值给boolean型变量ba和bb。booleanba=68;/将表达式“68;/将表达式“68”赋值给变量bb课件制作人:XXX2.3.2引用数据类型引用数据类型包括类引用、接口引用以及数组引用。下面的代码分别声明一个java.lang.Object类的引用、java.util.List接口的引用和一个int型数组的引用。说明:将引用数据类型的常量或变量初始化为null时,表示引用数据类型的常量或变量不引用任何对象。Objectobject=null;/声明一个Object类的引用变量L

30、istlist=null;/声明一个List接口的引用变量intmonths=null;/声明一个int型数组的引用变量课件制作人:XXX2.3.3基本类型与引用类型的区别基本数据类型与引用数据类型主要区别在以下两个方面:n基本数据类型与引用数据类型的组成nJava虚拟机处理基本数据类型变量与引用数据类型变量的方式。课件制作人:XXX组成基本数据类型是一个单纯的数据类型,它表示的是一个具体的数字、字符或逻辑值,例如68、M或true对于引用数据类型,若一个变量引用的是一个复杂的数据结构的实例,则该变量的类型就属于引用数据类型在引用数据类型变量所引用的实例中,不仅可以包含基本数据类型的变量,还可

31、以包含对这些变量的具体操作行为,甚至是包含其他引用类型的变量。课件制作人:XXX组成【例2.2】基本数据类型与引用数据类型例如:n创建一个档案类Recordn在该类中利用引用类型变量name存储姓名n利用char型变量sex存储性别n利用int型变量age存储年龄n利用boolean型变量married存储婚姻状况n提供一些操作这些变量的方法n创建档案类Record的引用变量课件制作人:XXXJava虚拟机的处理方式对于基本数据类型的变量,Java虚拟机会根据变量的实际类型为其分配内存空间。例如为int型变量分配4个字节的内存空间。而引用类型的变量,Java虚拟机在内存空间中存放的并不是变量所

32、引用的对象,而是对象在堆内存中存放的地址,所以引用变量最终只是指向被引用的对象,而不是存储引用对象的数据,因此两个引用变量之间的赋值,就是将一个引用变量存储的地址复制给另一个引用变量,从而使两个变量指向同一个对象。课件制作人:XXX例如创建一个图书类Book:声明两个Book类的实例,分别通过变量book1和book2进行引用,对book1进行具体的初始化,而将book2初始化为null,具体代码如下。publicclassBookStringisbn=“978-7-115-16451-3”;Stringname=“应用开发完全手册”;Stringauthor=“科技”;floatprice=

33、59.00F;Bookbook1=newBook();Bookbook2=null;课件制作人:XXXJava虚拟机为引用变量book1、book2及book1所引用对象的成员变量分配的内存空间如下图所示。从图中可以看出,变量book1引用了Book类的实例,book2没有引用任何实例。课件制作人:XXX下面对变量book2进行具体的初始化,将book1引用实例的地址复制给book2变量,即book2与book1引用同一个Book类的实例,具体代码如下:book2=book1;此时Java虚拟机的内存空间分配情况如下图所示。课件制作人:XXX2.3.4数据类型之间的相互转换所谓数据类型之间的相

34、互转换,就是将变量从当前的数据类型转换为其他数据类型。在Java中数据类型之间的相互转换可以分为以下3种情况:n基本数据类型之间的相互转换;n字符串与其他数据类型之间的相互转换;n引用数据类型之间的相互转换。说明:这里只介绍基本数据类型之间的相互转换,其他两种情况将在相关的章节中介绍。课件制作人:XXX2.3.4数据类型之间的相互转换在对多个基本数据类型的数据进行混合运算时,如果这几个数据并不属于同一基本数据类型,需要先将它们转换为统一的数据类型,然后才能进行运算。基本数据类型之间的相互转换又分为两种情况:n自动类型转换n强制类型转换。课件制作人:XXX1自动类型转换当需要从低级类型向高级类型

35、转换时,编程人员无需进行任何操作,Java会自动完成类型转换。低级类型是指取值范围相对较小的数据类型,高级类型则指取值范围相对较大的数据类型,例如long型相对于float型是低级数据类型,但是相对于int型则是高级数据类型。在基本数据类型中,除了boolean类型外均可参与算术运算,这些数据类型从低到高的排序如下图所示。课件制作人:XXX自动类型转换在不同数据类型间的算术运算中,自动类型转换可以分为两种情况进行考虑:n第一种情况含有int、long、float或double型的数据n第二种情况含有byte、short或char型的数据。课件制作人:XXX自动类型转换第一种情况如果在算术表达式

36、中含有int、long、float或double型的数据,Java首先会将所有数据类型较低的变量自动转换为表达式中最高的数据类型,然后再进行计算,并且计算结果的数据类型是表达式中级别最高的数据类型。课件制作人:XXX例如下面这段代码:Java首先会自动将表达式“b*c-i+l”中的变量b、c和i的数据类型转换为long型。然后再进行计算,并且计算结果的数据类型为long型。所以将表达式“b*c-i+l”直接赋值给数据类型相对小于long型(例如int型)的变量是不允许的,但是可以直接赋值给数据类型相对大于long型(例如float型)的变量。byteb=75;charc=c;inti=7942

37、15;longl=9876543210L;long result = b * c - i + l;课件制作人:XXX再看下面这段代码:Java首先会自动将表达式“b*c-i+d”中的变量b、c和i的数据类型转换为double型,然后再进行计算,并且计算结果的数据类型为double型。所以将表达式“b*c-i+d”直接赋值给数据类型相对小于double型(例如long型)的变量是不允许的。byteb=75;charc=c;inti=794215;doubled=11.17;double result = b * c - i + d;课件制作人:XXX自动类型转换第二种情况如果在算术表达式中只含有

38、byte、short或char型的数据,Java首先会将所有变量的类型自动转换为int型,然后再进行计算,并且计算结果的数据类型是int型。课件制作人:XXX例如下面这段代码:Java首先会自动将表达式“b+s*c”中的变量b、s和c的数据类型转换为int型,然后再进行计算,并且计算结果的数据类型为int型。所以将表达式“b+s*c”直接赋值给数据类型小于int型(例如char型)的变量是不允许的,但是可以直接赋值给数据类型相对大于int型(例如long型)的变量。byteb=75;shorts=9412;charc=c;int result = b + s * c;课件制作人:XXX再看下面

39、这段代码:即使是在这段代码中,Java也会自动将表达式“s1*s2”中的变量s1和s2的数据类型转换为int型,然后再进行计算,并且计算结果的数据类型也为int型。对于数据类型为byte、short、int、long、float和double的变量,可以将数据类型较小的数据或变量,直接赋值给数据类型较大的变量,但是相反的条件则不成立。shorts1=75;shorts2=9412;int result = s1 * s2;课件制作人:XXX2强制类型转换如果需要把数据类型较高的数据或变量赋值给数据类型相对较低的变量,就必须进行强制类型转换。例如将Java默认为double型的数据“7.5”,赋

40、值给数据类型为int型变量的方式如下:inti=(int)7.5;这句代码在数据“7.5”的前方添加了代码“(int)”,意思就是将数据“7.5”的类型强制转换为int型。在执行强制类型转换时,可能会导致数据溢出或精度降低。例如上面语句中变量i的值最终为7,导致数据精度降低。课件制作人:XXX2强制类型转换如果将Java默认为int型的数据“774”赋值给数据类型为byte型变量,方法如下:byteb=(byte)774;最终变量b的值为6,原因是整数774超出了byte型的取值范围,在进行强制类型转换时,整数774的二进制数据的前24位将被舍弃,变量b的数值是后8位的二进制数据,如下图所示。

41、课件制作人:XXX2.4运算符Java语言中的运算符主要包括:n赋值运算符n算术运算符n关系运算符n逻辑运算符n位运算符下面介绍各个运算符的使用方法。课件制作人:XXX2.4.1赋值运算符赋值运算符的符号为“=”,它的作用是将数据、变量、对象赋值给相应类型的变量,例如下面的代码:赋值运算符的运算顺序为从右到左。例如在下面的代码中,首先是计算表达式“9412+75”的和,然后将计算结果赋值给变量result:inti=75;/将数据赋值给变量longl=i;/将变量赋值给变量Objectobject=newObject();/创建对象intresult=9412+75;课件制作人:XXX赋值运算

42、符如果两个变量的值相同,也可以采用下面的方式完成赋值操作:intx,y;/声明两个int型变量x=y=0;/为两个变量同时赋值课件制作人:XXX2.4.2算术运算符算术运算符支持整数型数据和浮点数型数据的运算,当整数型数据与浮点数型数据之间进行算术运算时,Java会自动完成数据类型的转换,并且计算结果为浮点数型。运 算 符功 能举 例运 算 结 果结 果 类 型+加法运算10 + 7.517.5double-减法运算10 7.5F2.5Ffloat*乘法运算3 * 721int/除法运算21 / 3L7Llong%求余运算10 % 31int课件制作人:XXX算术运算符在进行算术运算时,有两种

43、情况需要考虑:n没有小数参与运算n有小数参与运算。课件制作人:XXX没有小数参与运算在对整数型数据或变量进行加法(+)、减法(-)和乘法(*)运算时,与数学中的运算方式完全相同,但是在整数之间进行除法(/)和求余(%)运算时需要注意几个问题。n注意除法运算n注意求余运算n关于0的问题课件制作人:XXX除法运算在整数类型的数据和变量之间进行除法运算时,无论能否整除,运算结果都将是一个整数,而且这个整数不是通过四舍五入得到的,而是简单地去掉小数部分。例如通过下面的代码分别计算10除以3和5除以2,最终输出的运算结果依次为3和2:System.out.println(10/3);/输出运算结果为3S

44、ystem.out.println(5/2);/输出运算结果为2课件制作人:XXX求余运算在整数类型的数据和变量之间进行求余(%)运算时,运算结果是数学运算中余数。例如通过下面的代码分别计算10%3、10%5和10%7,最终输出的运算结果依次为1、0和3:System.out.println(10%3);/输出运算结果为1System.out.println(10%5);/输出运算结果为0System.out.println(10%7);/输出运算结果为3课件制作人:XXX关于0的问题与数学运算一样,0可以做被除数,但是不可以做除数。当0做被除数时,无论是除法运算,还是求余运算,运算结果都为0

45、。例如通过下面的代码分别计算0除以6和0除以6求余数,最终输出的运算结果均为0:注意:如果0做除数,虽然可以编译成功,但是在运行时会抛出java.lang.ArithmeticException异常,即算术运算异常。System.out.println(0/6);/输出运算结果为0System.out.println(0%6);/输出运算结果为0课件制作人:XXX有小数参与运算在对浮点数类型的数据或变量进行算术运算时,如果在算术表达式中含有double类型的数据或变量,则运算结果为double型,否则运算结果为float型。在对浮点数类型数据或变量进行算术运算时,计算机的计算结果可能会在小数点

46、后包含n位小数,这些小数在有些时候并不是精确的,计算机的计算结果会与数学运算的结果存在一定的误差,只能是尽量接近数学运算中的结果。课件制作人:XXX有小数参与运算如果被除数为浮点型数据或变量,无论是除法运算,还是求余运算,0都可以做除数。如果是除法运算,当被除数是正数时,运算结果为Infinity,表示无穷大,当被除数是负数时,运算结果为-Infinity,表示无穷小;如果是求余运算,运算结果为NaN,表示非数字。例如下面的代码:System.out.println(7.5/0);/输出的运算结果为InfinitySystem.out.println(-7.5/0); /输出的运算结果为-In

47、finitySystem.out.println(7.5%0); /输出的运算结果为NaNSystem.out.println(-7.5%0); /输出的运算结果为NaN课件制作人:XXX2.4.3关系运算符关系运算符用于比较大小,运算结果为boolean型,当关系表达式成立时,运算结果为true,否则运算结果为false。运算符功能举例结果可运算数据类型大于a bfalse整数、浮点数、字符小于2 =大于或等于6.6 = 8.8false整数、浮点数、字符=小于或等于M = 88true整数、浮点数、字符要注意关系运算符“=”和赋值运算符“=”的区别!课件制作人:XXX2.4.4逻辑运算符逻

48、辑运算符用于对boolean型数据进行运算,运算结果仍为boolean型。Java中的逻辑运算符包括:n!(取反)n(异或)n&(与)n|(或)n&(简洁与)n|(简洁或)下面将依次介绍各个运算符的用法和特点。课件制作人:XXX取反运算符“!”运算符“!”用于对逻辑值进行取反运算,当逻辑值为true时,经过取反运算后运算结果为false,否则当逻辑值为false时,经过取反运算后运算结果则为true,例如下面的代码:System.out.println(!true);/输出结果为falseSystem.out.println(!false);/输出结果为true课件制作人:XXX异或运算符“”

49、运算符“”用于对逻辑值进行异或运算,当运算符的两侧同时为true或false时,运算结果为false,否则运算结果为true。例如下面的代码:System.out.println(truetrue);/输出的运算结果为falseSystem.out.println(truefalse);/输出的运算结果为trueSystem.out.println(falsetrue);/输出的运算结果为trueSystem.out.println(falsefalse);/输出的运算结果为false课件制作人:XXX运算符“&”和“&”运算符“&”和“&”均用于逻辑与运算,当运算符的两侧同时为true时,运

50、算结果为true,否则运算结果均为false。例如下面的代码:System.out.println(true&true);/输出结果为trueSystem.out.println(true&false);/输出结果为falseSystem.out.println(false&true);/输出结果为falseSystem.out.println(false&false);/输出结果为falseSystem.out.println(true&true);/输出结果为trueSystem.out.println(true&false);/输出结果为falseSystem.out.println(f

51、alse&true);/输出结果为falseSystem.out.println(false&false);/输出结果为false课件制作人:XXX运算符“&”和“&”的区别运算符“&”为简洁与运算符,运算符“&”为非简洁与运算符,它们的区别如下:n运算符“&”只有在其左侧为true时,才运算其右侧的逻辑表达式,否则直接返回运算结果false。n运算符“&”无论其左侧为true或false,都要运算其右侧的逻辑表达式,最后才返回运算结果。课件制作人:XXX运算符“|”和“|”运算符“|”和“|”均用于逻辑或运算,当运算符的两侧同时为false时,运算结果为false,否则运算结果均为true,

52、例如下面的代码:System.out.println(true|true);/输出的运算结果为trueSystem.out.println(true|false);/输出的运算结果为trueSystem.out.println(false|true);/输出的运算结果为trueSystem.out.println(false|false);/输出的运算结果为falseSystem.out.println(true|true);/输出的运算结果为trueSystem.out.println(true|false);/输出的运算结果为trueSystem.out.println(false|tru

53、e);/输出的运算结果为trueSystem.out.println(false|false);/输出的运算结果为false课件制作人:XXX运算符“|”和“|”的区别运算符“|”为简洁或运算符,运算符“|”为非简洁或运算符,它们的区别如下:n运算符“|”只有在其左侧为false时,才运算其右侧的逻辑表达式,否则直接返回运算结果true。n运算符“|”无论其左侧为true或false,都要运算其右侧的逻辑表达式,最后才返回运算结果。课件制作人:XXX2.4.5位运算符位运算是对操作数以二进制位为单位进行的操作和运算,运算结果均为整数型。位运算符又分为逻辑位运算符和移位运算符两种。课件制作人:X

54、XX逻辑位运算符逻辑位运算符包括:n“”(按位取反)n“&”(按位与)n“|”(按位或)n“”(按位异或)它们用来对操作数进行按位运算,运算规则如下表所示。课件制作人:XXX逻辑位运算符按位取反运算是将二进制位中的0修改为1,1修改为0;在进行按位与运算时,只有当两个二进制位都为1时,结果才为1;在进行按位或运算时,只要有一个二进制位为1,结果就为1;在进行按位异或运算时,当两个二进制位同时为0或1时,结果为0,否则结果为1。操作数x操作数yxx&yx|yxy001000011011100011110110课件制作人:XXX移位运算符移位运算符包括:n“”(右移,高位添符号位)n“”(无符号右

55、移,高位添0补齐)它们用来对操作数进行移位运算。【例2-4】移位运算符的运算规则。课件制作人:XXX2.4.6对象运算符(instanceof)对象运算符用来判断对象是否为某一类型,运算结果为boolean型,如果是则返回true,否则返回false,对象运算符的关键字为“instanceof”,它的用法为:对象标识符instanceof类型标识符例如:java.util.Datedate=newjava.util.Date();System.out.println(dateinstanceofjava.util.Date);/结果为trueSystem.out.println(dateins

56、tanceofjava.sql.Date);/结果为false课件制作人:XXX2.4.7其他运算符Java中除了前面介绍的几类运算符外,还有一些不属于上述类别的运算符,如下表所示。运算符说 明运算结果类型+一元运算符,自动递增与操作元的类型相同- -一元运算符,自动递减与操作元的类型相同?:?:三元运算符,根据“?”左侧的逻辑值,决定返回“:”两侧中的一个值,类似ifelse流程控制语句与返回值的类型相同 用于声明、建立或访问数组的元素数组类型. .访问类的成员或对象的实例成员若访问的是成员变量,则类型与该成员变量相同;若访问的是方法,则类型与该方法的返回值相同课件制作人:XXX自动递增、递

57、减运算符与C、C+类似,Java语言也提供了自动递增与递减运算符,其作用是自动将变量值加1或减1。它们既可以放在操作元的前面,也可以放在操作元的后面,根据运算符位置的不同,最终得到的结果也是不同的。放在操作元前面的自动递增、递减运算符,会先将变量的值加1,然后再使该变量参与表达式的运算课件制作人:XXX自动递增、递减运算符放在操作元后面的递增、递减运算符,会先使变量参与表达式的运算,然后再将该变量加1。例如:intnum1=3;intnum2=3;inta=2+(+num1);/先将变量num1加1,然后再执行“2+4”intb=2+(num2+);/先执行“2+3”,然后再将变量num2加1

58、课件制作人:XXX三元运算符“?:”三元运算符“?:”的应用形式如下:三元运算符“?:”的运算规则为:若逻辑表达式的值为true,则整个表达式的值为表达式1的值,否则为表达式2的值。例如:这段代码的输出结果为“库存量:12”逻辑表达式?表达式1:表达式2intstore=12;System.out.println(store=5?库存不足!:库存量:+store);课件制作人:XXX2.4.8运算符的优先级别及结合性当在一个表达式中存在多个运算符进行混合运算时,会根据运算符的优先级别来决定运算顺序,优先级最高的是括号“()”,它的使用与数学运算中的括号一样,只是用来指定括号内的表达式要优先处理

59、。例如:intnum=8*(4+6);/num为80课件制作人:XXX2.4.8运算符的优先级别及结合性对于处在同一层级的运算符,则按照它们的结合性,即“先左后右”还是“先右后左”的顺序来执行。Java中除赋值运算符的结合性为“先右后左”外,其他所有运算符的结合性都是“先左后右”。关于运算符优先级的顺序,如下表所示。课件制作人:XXX优 先 级说 明运 算 符最高括号()后置运算符.正负号+-一元运算符+-!乘除运算*/%加减运算+-移位运算比较大小=比较是否相等=!=按位与运算&按位异或运算按位或运算|逻辑与运算&逻辑或运算|三元运算符?:最低赋值及复合赋值=*=/=%=+=-=&=|=课件

60、制作人:XXX2.5字符串在Java语言中,提供了一个专门用来操作字符串的类java.lang.String,在本节将学习该类的使用方法。课件制作人:XXX2.5.1创建字符串对象声明并初始化字符串的常用语法如下:在初始化字符串对象时,可以将字符串对象初始化为空值,也可以初始化为具体的字符串。例如下面的代码:String字符串变量=字符串;StringaStr=null;/初始化为空值StringbStr=“”;/初始化为空字符串StringcStr=“MWQ”;/初始化为“MWQ”课件制作人:XXX2.5.2连接字符串连接字符串可以通过运算符“+”实现,与算术运算中的意义是不同的,这里的“+

61、”符号意思是将多个字符串合并到一起生成一个新的字符串。对于“+”运算符,如果有一个操作元为String类型,则为字符串连接运算符,将生成新的字符串。【例2-5】通过运算符“+”连接字符串。Stringlove=“耐心”+“真心”;StringaStr=“单价:”+5元;/“单价:5元”StringbStr=“15”+15;/“1515”课件制作人:XXX2.5.3字符串操作在使用字符串时,经常需要对字符串进行处理,以满足一定的要求。常用的字符串操作包括:n比较字符串n获取字符串的长度n字符串的大小写转换n查找字符串n截取子字符串n去掉字符串的首尾空格n替换字符串中的字符或子串n分割字符串课件制

62、作人:XXX比较字符串String类定义了几个用于比较字符串的方法,这些方法包括:nequals()方法nequalsIgnoreCase()方法nstartsWith()方法和endsWith()方法ncompareTo()方法课件制作人:XXX比较字符串equals()方法由于字符串是对象类型,所以不能简单地用“=”(双等号)判断两个字符串是否相等,所以String类定义了equals()方法用于比较两个字符串是否相等。equals()方法的定义如下:str参数是要比较的字符串对象,该方法的返回值为boolean型。例如比较字符串“A”和字符串“a”是否相等:注意:equals()方法在比

63、较两个字符串时区分字母大小写。publicbooleanequals(Stringstr)Stringstr=A;booleanb=str.equals(“a”);/比较结果b为false课件制作人:XXX比较字符串equalsIgnoreCase()方法这个方法也用来比较两个字符串,不过它与equals()方法是有区别的,equalsIgnoreCase()方法在比较两个字符串时不区分大小写,该方法的定义如下:下面用equalsIgnoreCase()方法比较字符串“A”和字符串“a”是否相等:注意:equalsIgnoreCase()方法不区分字母大小写。publicbooleanequa

64、lsIgnoreCase(Stringstr)Stringstr=A;booleanb=str.equalsIgnoreCase(a);/比较结果b为true课件制作人:XXX比较字符串startsWith()和endsWith()方法这两方法分别用于判断字符串是否以指定的字符串开始或结束,它们的定义如下:参数prefix和suffix为欲比较的字符串对象,该方法的返回值为boolean型,例如分别判断字符串“ABCDE”是否以字符串“a”开始以及以字符串“DE”结束:publicbooleanstartsWith(Stringprefix)publicbooleanendsWith(Stri

65、ngsuffix)Stringstr=ABCDE;booleanbs=str.startsWith(“a”);/比较结果bs为falsebooleanbe=str.endsWith(DE); /比较结果be为true课件制作人:XXXstartsWith()还有一个重载方法,可以指定索引位置开始是否为指定的字符串,重载方法定义如下:方法的第二个参数toffset是比较字符串的索引位置。例如下面的代码判断字符串“ABCDE”从索引位置2开始是否为字符串“CD”:上面代码的判断结果为true,即字符串“ABCDE”从索引位置2开始是字符串“CD”。publicbooleanstartsWith(S

66、tringprefix,inttoffset)Stringstr=ABCDE;booleanb=str.startsWith(CD,2);课件制作人:XXX获取字符串的长度字符串是一个对象,在这个对象中包含length属性,它是该字符串的长度,使用String类中的length()方法可以获取该属性值。例如获取字符串“MingRiSoft”长度的代码如下:StringnameStr=MingRiSoft;inti=nameStr.length();/获得字符串的长度为10课件制作人:XXX字符串的大小写转换在String类中提供了两个用来实现字母大小写转换的方法toLowerCase()和to

67、UpperCase(),它们的返回值均为转换后的字符串,其中方法toLowerCase()用来将字符串中的所有大写字母改为小写字母,方法toUpperCase()用来将字符串中的小写字母改为大写字母。例如将字符串“AbCDefGh”分别转换为大写和小写,具体代码如下:Stringstr=AbCDefGh;StringlStr=str.toLowerCase();/结果为“abcdefgh”StringuStr=str.toUpperCase();/结果为“ABCDEFGH”课件制作人:XXX查找字符串String类提供了两种查找字符串的方法,它们允许在字符串中搜索指定的字符或字符串。其中ind

68、exOf()方法用于搜索字符或字符串首次出现的位置。lastIndexOf()方法用于搜索字符或字符串最后一次出现的位置。这两种方法均有多个重载方法,它们的返回值均为字符或字符串被发现的索引位置,如果未搜索到字符串则返回-1。下面将介绍这些重载的方法:课件制作人:XXX查找字符串nindexOf(intch):获取指定字符在原字符串中第一次出现的索引。nlastIndexOf(intch):获取指定字符在原字符串中最后一次出现的索引。nindexOf(Stringstr):获取指定字符串在原字符串中第一次出现的索引。nlastIndexOf(Stringstr):获取指定字符在原字符串中最后一

69、次出现的索引。nindexOf(intch,intstartIndex):用于获取指定字符在原字符串中指定索引位置开始第一次出现的索引。nlastIndexOf(intch,intstartIndex):用于获取指定字符在原字符串中指定索引位置开始最后一次出现的索引。nindexOf(Stringstr,intstartIndex):用于获取指定字符串在原字符串中指定索引位置开始第一次出现的索引。nlastIndexOf(Stringstr,intstartIndex):用于获取指定字符在原字符串中指定索引位置开始最后一次出现的索引。课件制作人:XXX查找字符串例如下面的代码:Stringst

70、r=mingrikeji;inti=str.indexOf(i);System.out.println(字符i第一次出现在索引:+i);/索引值是1i=str.lastIndexOf(i);System.out.println(字符i最后一次出现在索引:+i);/索引值是9i=str.lastIndexOf(ri);System.out.println(字符串ing第一次出现在索引:+i);/索引值是4i=str.lastIndexOf(ri);System.out.println(字符串ing最后一次出现在索引:+i);/索引值是4i=str.lastIndexOf(i,4);System.

71、out.println(从第5个字符开始,字符i第一次出现在索引:+i);/索引值是1课件制作人:XXX截取子字符串通过String类的substring()方法,可以从现有字符串中截取子字符串,有两个重载方法,具体定义如下:方法substring(intbeginIndex)用来截取从指定索引位置到最后的子字符串,截取得到的字符串包含指定索引位置的字符。publicStringsubstring(intbeginIndex)publicStringsubstring(intbeginIndex,intendIndex)课件制作人:XXX截取子字符串例如下面的代码截取字符串“ABCDEF”从索

72、引位置3到最后得到的子串为“DEF”,在子串“DEF”中包含字符串“ABCDEF”中索引为3的字符D:Stringstr=ABCDEF;System.out.println(str.substring(3);/截取得到的子串为“DEF”课件制作人:XXX截取子字符串方法substring(intbeginIndex,intendIndex)用来截取从起始索引位置beginIndex到终止索引位置endIndex的子字符串,截取得到的字符串包含起始索引位置beginIndex对应的字符,但是不包含终止索引位置endIndex对应的字符。例如下面的代码截取字符串“ABCDEF”从起始索引位置2到终

73、止索引位置4得到的子串为“CD”,在子串“CD”中包含字符串“ABCDEF”中索引为2的字符C,但是不包含字符串“ABCDEF”中索引为4的字符E:Stringstr=ABCDEF;System.out.println(str.substring(2,4);/截取得到的子串为“CD”课件制作人:XXX去掉字符串的首尾空格通过String类的trim()方法,可以通过去掉字符串的首尾空格得到一个新的字符串,该方法的具体定义如下:例如通过去掉字符串“ABC”中的首尾空格将得到一个新的字符串“ABC”,例如下面的代码分别输出字符串的长度为5和3:publicStringtrim()Stringstr

74、=ABC;/定义一个字符串,首尾均有空格System.out.println(str.length();/输出字符串的长度为5Stringstr2=str.trim();/去掉字符串的首尾空格System.out.println(str2.length();/输出字符串的长度为3课件制作人:XXX替换字符串中的字符或子串通过String类的replace()方法,可以将原字符串中的某个字符替换为指定的字符,并得到一个新的字符串,该方法的具体定义如下:例如将字符串“NBA_NBA_NBA”中的字符“N”替换为字符“M”,将得到一个新的字符串“MBA_MBA_MBA”,具体代码如下:publicS

75、tringreplace(charoldChar,charnewChar)Stringstr=NBA_NBA_NBA;System.out.println(str.replace(N,M);/输出MBA_MBA_MBA课件制作人:XXX替换字符串中的字符或子串如果想替换掉原字符串中的指定子串,可以通过String类的replaceAll()方法,该方法的具体定义如下:例如将字符串“NBA_NBA_NBA”中的子串“NB”替换为字符串“AA”,将得到一个新的字符串“AAA_AAA_AAA”,具体代码如下:publicStringreplaceAll(Stringregex,Stringrepla

76、cement)Stringstr=NBA_NBA_NBA;System.out.println(str.replaceAll(NB,AA);/输出的新字符串为AAA_AAA_AAA课件制作人:XXX替换字符串中的字符或子串如果只需要替换原字符串中的第一个子串,可以通过String类的replaceFirst()方法,该方法的具体定义如下:例如将字符串“NBA_NBA_NBA”中的第一个子串“NB”替换为字符串“AA”,将得到一个新的字符串“AAA_NBA_NBA”,具体代码如下:publicStringreplaceFirst(Stringregex,Stringreplacement)Str

77、ingstr=NBA_NBA_NBA;System.out.println(str.replaceFirst(NB,AA);/输出的新字符串为AAA_NBA_NBA课件制作人:XXX分割字符串在String类中提供了两个重载的split()方法,用来将字符串按照指定的规则进行分割,并以String型数组的方式返回,分割得到的子串在数组中的顺序按照它们在字符串中的顺序排列。方法的具体定义如下:publicStringsplit(Stringregex,intlimit)课件制作人:XXX分割字符串该方法的第一个参数regex为分割规则,第二个入口参数limit用来设置分割规则的应用次数,所以将影

78、响返回的结果数组的长度。如果limit大于0,则分割规则最多将被应用(limit-1)次,数组的长度也不会大于limit,并且数组的最后一项将包含超出最后匹配的所有字符。如果limit为负数,则分割规则将被应用尽可能多的次数,并且数组可以是任意长度;需要注意的是,如果limit为0,数组中位于最后的所有空字符串元素将被丢弃。课件制作人:XXX分割字符串下面将字符串“boo:and:foo”分别按照不同的规则和限制进行分割:Stringstr=boo:and:foo;Stringa=str.split(:,2);Stringb=str.split(:,5);Stringc=str.split(:

79、,-2);Stringd=str.split(o,5);Stringe=str.split(o,-2);Stringf=str.split(o,0);Stringg=str.split(m,0);课件制作人:XXX分割字符串上面代码得到的7个数组的相关信息如下表所示。数 组分 割 符限 定 数得到的数组a:2String a = boo, and:foo ;b:5String b = boo, and, foo ;c:-2String c = boo, and, foo ;do5String d = b, , :and:f, , ;eo-2String e = b, , :and:f, , ;

80、fo0String f = b, , :and:f ;gm0String g = boo:and:foo ;课件制作人:XXX分割字符串如果是将参数limit设置为0,也可以采用重载方法split(Stringregex),该方法将调用方法split(Stringregex,intlimit),并默认参数limit为0,方法的具体定义如下:publicStringsplit(Stringregex)returnsplit(regex,0);课件制作人:XXX2.5.4格式化字符串通过String类的format()方法,可以得到经过格式化的字符串对象,最常用的是对日期和时间的格式化。Strin

81、g类中的format()方法有两种重载形式,它们的具体定义如下:参数format为要获取字符串的格式;参数args为要进行格式化的对象;参数locale为格式化字符串时依据的语言环境。format(Stringformat,Objectobj)方法将依据本地的语言环境进行格式化。publicstaticStringformat(Stringformat,Objectobj)publicstaticStringformat(Localelocale,Stringformat,Objectobj)课件制作人:XXX格式化字符串格式化字符串采用的格式如下表所示。转 换 符功 能 说 明转换符功能说明

82、%s格式化成字符串表示%a格式化成十六进制浮点数%c格式化成字符型表示%e格式化成指数形式表示%b格式化成逻辑型表示%g格式化成通用浮点数型数表示(f和e类型中较短的)%d格式化成十进制整型数表示%h格式化成散列码形式表示%x格式化成十六进制整型数表示%格式化成百分比形式表示%o格式化成八进制整型数表示%n换行符%f格式化成十进制浮点数型数表示%tx格式化成日期和时间形式表示(其中x代表不同的日期与时间转换符)课件制作人:XXX格式化字符串下面是三个获取格式化字符串的例子,分别为获得字符A的散列码、将68格式化为百分比形式和将16.8格式化为指数形式,代码如下:Stringcode=Strin

83、g.format(“%h”,A);/结果为“41”Stringpercent=String.format(“%d%”,68);/结果为“68%”Stringexponent=String.format(“%e”,16.8);/结果为“1.680000e+01”课件制作人:XXX2.5.5格式化日期和时间在使用日期和时间时,经常需要对其进行格式处理,以满足一定的要求。例如将日期格式化为“2008-01-27”形式,将时间格式化为“03:06:52下午”形式,或者是获得4位的年(例如“2008”)或24小时的时(例如“21”)。日期和时间的格式化主要包括:n常用日期和时间的格式化n对日期的格式化n

84、对时间的格式化课件制作人:XXX常用日期和时间的格式化格式化日期与时间的转换符定义了各种格式化日期字符串的方式,其中最常用的如下表所示。转 换 符格 式 说 明格 式 示 例F格式化为形如“YYYY-MM-DD”的格式2008-01-26D格式化为形如“MM/DD/YY”的格式01/26/08r格式化为形如“HH:MM:SS AM”的格式(12小时制)03:06:52 下午T格式化为形如“HH:MM:SS”的格式(24小时制)15:06:52R格式化为形如“HH:MM”的格式(24小时制)15:06课件制作人:XXX常用日期和时间的格式化下面代码是对当前日期和时间进行格式化的举例:String

85、a=String.format(“%tF”,today);/结果为:2008-01-26Stringb=String.format(“%tD”,today);/结果为:01/26/08Stringc=String.format(“%tr”,today);/结果为:03:06:52下午Stringd=String.format(“%tT”,today);/结果为:15:06:52Stringe=String.format(“%tR”,today);/结果为:15:06课件制作人:XXX对日期的格式化定义日期格式的转换符可以使日期通过指定的转换符生成新字符串。日期转换符如下表所示。转 换 符格 式

86、 说 明格 式 示 例b或h获取月份的简称中:一月 英:JanB获取月份的全称中:一月 英:Januarya获取星期的简称中:星期六 英:SatA获取星期的全称中:星期六 英:SaturdayY获取年(不足4位前面补0)2008y获取年的后两位(不足2位前面补0)08C获取年的前两位(不足2位前面补0)20m获取月(不足2位前面补0)01d获取日(不足2位前面补0)06e获取日(不足2位前面补0)6j获取是一年的第多少天006课件制作人:XXX对日期的格式化下面代码是对当前日期进行格式化的举例:Datetoday=newDate();Stringa=String.format(Locale.U

87、S,“%tb”,today);/JanStringb=String.format(Locale.US,%tB,today);/JanuaryStringc=String.format(%ta,today);/结果为:星期六Stringd=String.format(%tA,today);/结果为:星期六Stringe=String.format(%tY,today);/结果为:2008Stringf=String.format(%ty,today);/结果为:08Stringg=String.format(%tm,today);/结果为:01Stringh=String.format(%td,

88、today);/结果为:06Stringi=String.format(%te,today);/结果为:6Stringj=String.format(%tj,today);/结果为:006课件制作人:XXX对时间的格式化时间格式的转换符可以将时间格式化成时、分、秒甚至时毫秒等单位。转换符如下表所示。转换符格式说明格式示例H获取24小时制的小时(不足2位前面补0)15k获取24小时制的小时(不足2位前面不补0)15I获取12小时制的小时(不足2位前面补0)03l获取12小时制的小时(不足2位前面不补0)3M获取分钟(不足2位前面补0)06S获取秒(不足2位前面补0)09L获取3位的毫秒(不足3位

89、前面补0)015N获取9位的毫秒(不足9位前面补0)056200000p显示上下午标记中:下午英:pm课件制作人:XXX对时间的格式化下面代码是对当前时间进行格式化的举例:Datetoday=newDate();Stringa=String.format(“%tH”,today);/结果:16Stringb=String.format(%tk,today);/结果:16Stringc=String.format(%tI,today);/结果:04Stringd=String.format(%tl,today);/结果:4Stringe=String.format(%tM,today);/结果:

90、14Stringf=String.format(%tS,today);/结果:33Stringg=String.format(%tp,today);/结果:下午Stringh=String.format(Locale.US,%tp,today);/结果:pm课件制作人:XXX2.6数组数组是一种最为常见的数据结构,通过数组可以保存一组相同数据类型的数据,数组一旦创建,它的长度就固定了。数组的类型可以为基本数据类型,也可以为引用数据类型,可以是一维数据,二维数据,甚至是多维数据。课件制作人:XXX2.6.1一维数组声明一维数组的方式如下:这两种声明数组格式的作用是相同的。创建数组实质上就是在内存

91、中为数组分配相应的存储空间,有两种方式可以创建数组,一种是通过new关键字创建,另一种是通过“”创建,例如:数组类型数组标识符;数组类型数组标识符;intmonths=newint12;/months的长度为12booleanmembers=false,true,true,false; /members的长度为4课件制作人:XXX一维数组在访问数组中的元素时,需要同时指定数组标识符和元素在数组中的索引,例如访问上面代码中创建的数组,输出索引位置为2的元素,具体代码如下:执行这段代码,输出的内容为“0”和“true”,在通过new关键字创建数组时,得到的数组并没有被初始化,int型数组默认数组元

92、素均为0,而通过“”创建数组的同时就初始化了数组。System.out.println(months2);System.out.println(members2);课件制作人:XXX一维数组如果需要为数组中的某个元素赋值,方式如下:如果需要获得一维数组的长度,可以通过下面的方式:months2=68;members2=false;System.out.println(months.length);/输出值为12System.out.println(members.length);/输出值为4课件制作人:XXX2.6.2二维数组Java语言中的二维数组是一种特殊的一维数组,即数组的每个元素又是一

93、个一维数组,Java语言并不直接支持二维数组。声明二维数组的方式如下:例如分别声明一个int型和boolean型二维数组,具体代码如下:数组类型数组标识符;或数组类型数组标识符;intdays;booleanholidays;课件制作人:XXX二维数组创建数组实质上就是在内存中为数组分配相应的存储空间,有两种方式可以创建数组,一种是通过new关键字创建,另一种是通过“”创建,例如:二维数组可以看做一个表格。数组days看成一个2行3列的表格,数组holidays看成2行3列的表格intdays=newint23;booleanholidays=true,false,true,false,tru

94、e,false;列索引0列索引1列索引2行索引0days00days01days02行索引1days10days11days12课件制作人:XXX二维数组在访问数组中的元素时,需要同时指定数组标识符和元素在数组中的索引,例如访问上面代码中创建的数组,具体代码如下:如果是通过下面的方式获得二维数组的长度,得到的是二维数组的行数:如果需要获得二维数组的列数,可以通过下面的方式:System.out.println(days12);System.out.println(holidays12);System.out.println(days.length);/输出值为2System.out.print

95、ln(holidays.length);/输出值为2System.out.println(days0.length);/输出值为3System.out.println(holidays0.length);/输出值为3课件制作人:XXX二维数组如果是通过“”创建的数组,数组中每一行的列数也可以不相同,例如:通过下面的方式得到的只是第1行拥有的列数:如果需要获得二维数组中第2行和第3行拥有的列数,可以通过下面的方式:booleanholidays=true,false,true,/二维数组的第1行为3列false,true,/二维数组的第2行为2列true,false,true,false;/二维

96、数组的第3行为4列System.out.println(holidays0.length);/输出值为3System.out.println(holidays1.length);/输出值为2System.out.println(holidays2.length);/输出值为4JSP程序设计教程课件 制作人:XXXJava实用教程第3章程序流程控制语句课件制作人:XXX第3章程序流程控制语句3.1分支语句3.2循环语句3.3跳转语句课件制作人:XXX3.1分支语句分支语句就是对语句中不同条件的值进行判断,从而根据不同的条件执行不同的语句。Java语言的分支语句有以下两种。n条件语句nswitch

97、开关语句课件制作人:XXX条件语句条件语句可分为以下3种形式:(1)简单的if条件语句(2)if-else条件语句(3)if-elseif多分支条件语句课件制作人:XXX3.1.1 简单的if条件语句简单的if条件语句就是对某种条件做出相应的处理。通常表现为“如果满足某种情况,那么就进行某种处理”。它的一般形式为:例如:如果今天下雨,我们就不出去玩。条件语句为:if(表达式)语句序列if(今天下雨)我们就不出去玩课件制作人:XXX简单的if条件语句表达式是必要参数。其值可以由多个表达式组成,但是其最后结果一定是boolean类型,也就是其结果只能是true或false。语句序列是可选参数。包含

98、一条或多条语句,当表达式的值为true时执行这些语句。如果该语句只有一条语句,大括号也可以省略不写。下面的代码都是正确的。if(今天下雨);if(今天下雨)我们就不出去玩;课件制作人:XXX简单的if条件语句如图所示,if条件语句,在条件表达式的结果为true时,将执行语句序列。【例3-1】使用if语句求出c的最终结果。课件制作人:XXX3.1.2if.else条件语句ifelse条件语句也是条件语句的一种最通用的形式。else是可选的。通常表现为“如果满足某种条件,就做某种处理,否则做另一种处理”。它的一般形式为:if(表达式)语句序列1else语句序列2课件制作人:XXXif.else条件

99、语句语句序列1是可选参数。由一条或多条语句组成,当表达式的值为true时执行这些语句。语句序列2也是可选参数。包含一条或多条语句,当表达式的值为false时执行这些语句。例如:如果指定年为闰年,二月份为29天,否则二月份为28天。条件语句为:if(今年是闰年)二月份为29天else二月份为28天课件制作人:XXXif.else条件语句如图所示,ifelse语句在表达式的值为true时,执行语句序列1,否则,执行语句序列2。【例3-2】用ifelse语句判断69与29的大小课件制作人:XXX3.1.3if.elseif多分支语句ifelseif多分支语句用于针对某一事件的多种情况进行处理。通常表

100、现为“如果满足某种条件,就进行某种处理,否则如果满足另一种条件才执行另一种处理”。它的一般形式为:if(表达式1)语句序列1elseif(表达式2)语句序列2else语句序列n课件制作人:XXXif.elseif多分支语句语句序列1在表达式1的值为true时被执行,语句序列2在表达式2的值为true时被执行,语句序列n在表达式1的值为false,表达式2的值也为false时被执行。ifelseif多分支语句执行过程如下图所示。课件制作人:XXXif.elseif多分支语句例如:如果今天是星期一,上数学课;如果今天是星期二,上语文课;否则上自习。条件语句为:if(今天是星期一)上数学课elsei

101、f(今天是星期二)上语文课else上自习课件制作人:XXX3.1.4if语句的嵌套if语句的嵌套就是在if语句中又包含一个或多个if语句。这样的语句一般都用在比较复杂的分支语句中。它的一般形式为右侧的语句格式。在嵌套的语句中最好不要省略大括号。以提高代码的可读性。【例3-3】if(表达式1)if(表达式2)语句序列1else语句序列2elseif(表达式3)语句序列3else语句序列4课件制作人:XXX3.1.5switch多分支语句switch(表达式)case常量表达式1:语句序列1break;case常量表达式2:语句序列2break;case常量表达式n:语句序列nbreak;defa

102、ult:语句序列n+1break;switch语句是多分支的开关语句。根据表达式的值来执行输出的语句。这样的语句一般用于多条件多值的分支语句中。右侧是它的语法格式:break用于结束switch语句。课件制作人:XXXswitch多分支语句switch语句中表达式的值必须是整型或字符型。即int、short、byte和char型。Switch会根据表达式的值,执行符合常量表达式的语句序列。当表达式的值没有匹配的常量表达式时,则执行default定义的语句序列,即“语句序列n+1”。default是可选参数,如果没有该参数,并且所有常量值与表达式的值不匹配,那么switch语句就不会进行任何操作

103、。该语句执行流程如右图所示【例3-4】课件制作人:XXX3.1.6 if语句和switch语句的区别if语句和switch语句可以从使用的效率上来进行区别,也可以从实用性角度去区分。如果从使用的效率上进行区分,在对同一个变量的不同值作条件判断时,使用switch语句的效率相对更高一些,尤其是判断的分支越多越明显。如果从语句的实用性的角度去区分,那switch语句肯定不如if语句。if语句是应用最广泛和最实用的语句。课件制作人:XXX3.2循环语句循环语句就是重复执行某段程序代码,直到满足特定条件为止。在Java语言中循环语句有以下3种形式:nfor循环语句nwhile循环语句ndo-while

104、循环语句课件制作人:XXX3.2.1 for循环语句for语句是最常用的循环语句,一般用在循环次数已知的情况下。它的一般形式为:初始化语句用于初始化循环体变量。循环条件用于判断是否继续执行循环体。其只能是true或false。迭代语句用于改变循环条件的语句。语句序列称为循环体,当循环条件的结果为true时,将重复执行。for(初始化语句;循环条件;迭代语句)语句序列课件制作人:XXXfor循环语句for循环语句的流程首先执行初始化语句,然后判断循环条件,当循环条件为true时,就执行一次循环体,最后执行迭代语句,改变循环变量的值。这样就结束了一轮的循环。接下来进行下一次循环(不包括初始化语句)

105、,直到循环条件的值为false时,才结束循环。for循环语句执行过程如图所示。【例3-5】用for循环语句实现打印110的所有整数。课件制作人:XXX3.2.2while循环语句while语句是用一个表达式来控制循环的语句。它的一般形式为:表达式用于判断是否执行循环,它的值只能是true或false。当循环开始时,首先会执行表达式,如果表达式的值为true,则会执行语句序列,也就是循环体。当到达循环体的末尾时,会再次检测表达式,直到表达式的值为false,结束循环。while(表达式)语句序列课件制作人:XXXwhile循环语句while语句执行过程如图所示。【例3-6】计算199的整数和课件

106、制作人:XXXdo.while循环语句do.while循环语句称为后测试循环语句,它利用一个条件来控制是否要继续重复执行这个语句。它的一般形式为:dowhile循环语句的执行过程与while循环语句有所区别。dowhile循环至少被执行一次,它先执行循环体的语句序列,然后再判断是否继续执行。do语句序列while(表达式);课件制作人:XXXdo.while循环语句dowhile循环执行语句如图所示。【例3-7】计算1100的整数和。课件制作人:XXX3.2.4循环的嵌套循环的嵌套就是在一个循环体内又包含另一个完整的循环结构,而在这个完整的循环体内还可以嵌套其他的循环循结构。循环嵌套很复杂,在

107、for语句、while语句和dowhile语句中都可以嵌套。常用的嵌套循环包括:nfor循环语句的嵌套nwhile循环语句嵌套ndowhile循环语句嵌套nfor循环语句与while循环语句嵌套nwhile循环语句与for循环语句嵌套ndowhile循环语句与for循环语句嵌套【例3-8】打印九九乘法表。【例3-9】求100以内能被3和7整除的数。课件制作人:XXX3.3跳转语句Java语言中支持的跳转语句包括:nbreak跳转语句ncontinue跳转语句nreturn跳转语句。课件制作人:XXX3.3.1break跳转语句break语句可以终止循环或其他控制结构。它在for,while或d

108、owhile循环中,用于强行终止循环。只要执行到break语句,就会终止循环体的执行。break不仅在循环语句里适用,在switch多分支语句里也适用。【例3-10】 求10以内的素数。课件制作人:XXX3.3.2continue跳转语句continue语句应用在for,while和do.while等循环语句中,如果在某次循环体的执行中执行了continue语句,那么本次循环就结束,即不再执行本次循环中continue语句后面的语句,而进行下一次循环。【例3-11】求100以内被9整除的数。课件制作人:XXX3.3.3return跳转语句return语句可以从一个方法返回,并把控制权交给调用它

109、的语句。return语句通常被放在方法的最后,用于退出当前方法并返回一个值。它的语法格式为:return表达式;表达式是可选参数,表示要返回的值。它的数据类型必须同方法声明中的返回值类型一致。课件制作人:XXX例如:编写返回a和b两数相加之和的方法可以使用如下代码:如果方法没有返回值,可以省略return关键字的表达式,使方法结束。代码如下:publicintset(inta,intb)returnsum=a+b;publicvoidset(inta,intb)sum=a+b;return;JSP程序设计教程课件 制作人:XXXJava实用教程第4章面向对象基础课件制作人:XXX第4章面向对象

110、基础4.1面向对象程序设计4.2类和对象4.3包4.4继承4.5多态4.6特殊类4.7接口课件制作人:XXX4.2类和对象Java语言与其他面向对象语言一样,引入了类和对象的概念,类是用来创建对象的模板,它包含被创建对象的属性和方法的定义。因此,要学习Java编程就必须学会怎样去编写类,即怎样用Java的语法去描述一类事物共有的属性和行为。对象的属性通过变量来刻画,而对象的行为通过方法来体现。方法可以操作属性形成一定的算法来实现一个具体的功能。类把属性和方法封装成一个整体。课件制作人:XXX4.2.1定义类在Java语言中,类是基本的构成要素,是对象的模板,Java程序中所有的对象都是由类创建

111、的。一个Java类主要包括以下两部分:类的声明类的主体课件制作人:XXX类的声明在类声明中,需要定义类的名称、对该类的访问权限、该类与其他类的关系等。类声明的格式如下:修饰符用于指定类的访问权限,可选值为public、abstract和final。类名用于指定类的名称,类名必须是合法的Java标识符。一般情况下,要求首字母大写。extends 父类名用于指定要继承参数。implements 接口列表用于指定该类实现的所有接口。修饰符classextends父类名implements接口列表课件制作人:XXX类体类声明部分大括号中的内容为类体。类体主要由以下两部分构成:(1)成员变量的定义;(2

112、)成员方法的定义。在程序设计过程中,编写一个能完全描述客观事物的类是不现实的。比如,构建一个Apple类,该类可以拥有很多很多的属性(即成员变量),在定义该类时,选取程序需要的必要属性和行为就可以了。课件制作人:XXX4.2.2 了解成员方法Java中类的行为由类的成员方法来实现。类的成员方法由方法声明和方法体两部分组成。其一般格式如下:修饰符用于指定方法的访问权限,可选值为public、protected和private。方法返回值的类型用于指定该方法的返回值的类型,如果该方法没有返回值,必须使用关键字void进行标识。方法返回值的类型可以是任何Java数据类型。修饰符(参数列表)方法体课件

113、制作人:XXX了解成员方法方法名用于指定成员方法的名称,方法名必须是合法的Java标识符。参数列表用于指定方法中所需的参数。当存在多个参数时,各参数之间应使用逗号分隔。方法的参数可以是任何Java数据类型。方法体是方法的实现部分,在方法体中可以完成指定的工作,可以只打印一句话,也可以省略方法体,使方法什么都不做。需要注意的是:当省略方法体时,其外面的大括号一定不能省略。【例4-1】实现两数相加。课件制作人:XXX4.2.3成员变量和局部变量在类体中所声明的变量称为类的成员变量,而在方法体中声明的变量和方法的参数则称为局部变量。现在我们来看一下,如何声明成员变量和局部变量,以及变量的有效范围。课

114、件制作人:XXX声明成员变量Java用成员变量来表示类的状态和属性,声明成员变量的基本语法格式如下:修饰符:可选参数,用于指定变量的被访问权限,可选值为public、protected和private。static:可选,用于指定该成员变量为静态变量,可以直接通过类名访问。如果省略该关键字,则表示该成员变量为实例变量。final:可选,用于指定该成员变量为取值不会改变的常量。变量类型:必选:用于指定变量的数据类型,其值可以为Java中的任何一种数据类型。变量名:必选,用于指定成员变量的名称,变量名必须是合法的Java标识符。修饰符staticfinal;课件制作人:XXX声明成员变量例如,在类

115、中声明3个成员变量。publicclassApplepublicStringcolor;/声明公共变量colorpublicstaticintcount;/声明静态变量countpublicfinalbooleanMATURE=true; /声明常量MATURE并赋值publicstaticvoidmain(Stringargs)System.out.println(Apple.count);Appleapple=newApple();System.out.println(apple.color);System.out.println(apple.MATURE);课件制作人:XXX声明局部变量

116、定义局部变量的基本语法格式同定义成员变量类似,所不同的不能使用权限修是不和static关键字对局部变量进行修饰,但可以使用final关键字:final:可选,用于指定该局部变量为常量。变量类型:必选,用于指定变量的数据类型,其值可以为Java中的任何一种数据类型。变量名:必选,用于指定局部变量的名称,变量名必须是合法的Java标识符。final;课件制作人:XXX声明局部变量例如,在grow()成员方法中声明两个局部变量。publicvoidgrow()finalbooleanSTATE;/声明常量STATEintage;/声明局部变量age课件制作人:XXX变量的有效范围变量的有效范围是指该

117、变量在程序代码中的作用区域,在该区域外不能直接访问变量。有效范围决定了变量的生命周期,变量的生命周期是指从声明一个变量并分配内存空间、使用变量,然后释放该变量并清除所占用内存空间的一个过程。进行变量声明的位置,决定了变量的有效范围,根据有效范围的不同,可将变量分为以下两种。(1)成员变量:在类中声明,在整个类中有效。(2)局部变量:在方法内或方法内的复合代码块(“”与“”之间的代码)中声明的变量。在复合代码块声明的变量,只在当前复合代码块中有效;在复合代码块外、方法内声明的变量在整个方法内都有效。课件制作人:XXX变量的有效范围例如下面的实例:publicclassOlympicsprivat

118、eintmedal_All=800;/成员变量publicvoidChina()intmedal_CN=100;/方法的局部变量if(medal_CN1000)/代码块intgold=50;/代码块的局部变量medal_CN+=50;/允许访问medal_All-=150;/允许访问课件制作人:XXX4.2.4构造方法的概念及用途构造方法是一种特殊的方法,它的名字必须与它所在类的名字完全相同,并且没有返回值,也不需要使用关键字void进行标识。构造方法用于对对象中的所有成员变量进行初始化,在创建对象时立即被调用。【例4-2】publicclassApplepublicApple()/构造方法课

119、件制作人:XXX4.2.5对象生命周期在Java语言中,把任何事物都看做对象,例如一个人、一个动物,或者没有生命体的轮船、汽车、飞机,甚至概念性的抽象,例如公司业绩。一个对象在Java语言中的生命周期包括3个阶段:n创建对象n使用对象n销毁对象课件制作人:XXX创建对象对象是类的实例。Java定义任何变量都需要指定变量类型,因此,在创建对象之前,一定要先声明该对象。声明对象的一般格式如下:类名:用于指定一个已经定义的类。对象名:用于指定对象名称,对象名必须是合法的Java标识符。例如声明Apple类的一个对象redApple的代码如下:类名对象名;AppleredApple;课件制作人:XXX

120、创建对象在声明对象时,只是在内存中为其建立一个引用,并置初值为null,表示不指向任何内存空间。声明对象以后,需要为对象分配内存,这个过程也称为实例化对象。在Java中使用关键字new来实例化对象,具体语法格式如下:对象名:必选,用于指定已经声明的对象名。类名:必选,用于指定构造方法名,即类名,因为构造方法与类名相同。参数列表:可选参数,用于指定构造方法的入口参数。如果构造方法无参数,则可以省略。对象名=new构造方法名(参数列表);课件制作人:XXX创建对象在声明Apple类的一个对象redApple后,可以通过以下代码为对象redApple分配内存(即创建该对象):在声明对象时,也可以直接

121、实例化该对象:这相当于同时执行了对象声明和创建对象:AppleredApple=newApple();redApple=newApple();AppleredApple;redApple=newApple();课件制作人:XXX使用对象创建对象后,就可以访问对象的成员变量,并改变成员变量的值了,而且还可以调用对象的成员方法。通过使用运算符“.”实现对成员变量的访问和成员方法的调用。语法格式为:【例4-3】定义一个类,创建该类的对象,同时改变对象的成员变量的值并调用该对象的成员方法。对象.成员变量对象.成员方法()课件制作人:XXX销毁对象在许多程序设计语言中,需要手动释放对象所占用的内存,但是

122、,在Java中则不需要手动完成这项工作。Java提供的垃圾回收机制可以自动判断对象是否还在使用,并能够自动销毁不再使用的对象,收回对象所占用的资源。Java提供了一个名为finalize()的方法,用于在对象被垃圾回收机制销毁之前执行一些资源回收工作,由垃圾回收系统调用,可以重写该方法。但是垃圾回收系统的运行是不可预测的。finalize()方法没有任何参数和返回值,每个类有且只有一个finalize()方法。课件制作人:XXX4.3包Java要求文件名和类名相同,所以如果将多个类放在一起时,很可能出现文件名冲突的情况,这时Java提供了一种解决该问题的方法,那就是使用包将类进行分组。下面将对

123、Java中的包进行详细介绍。课件制作人:XXX4.3.1 包的概念包(package)是Java提供的一种区别类的命名空间的机制,是类的组织方式,是一组相关类和接口的集合,它提供了访问权限和命名的管理机制。Java中提供的包主要有以下3种用途。(1)将功能相近的类放在同一个包中,可以方便查找与使用。(2)由于在不同包中可以存在同名类,所以使用包在一定程度上可以避免命名冲突。(3)在Java中,某此访问权限是以包为单位的。课件制作人:XXX4.3.2创建包创建包可以通过在类或接口的源文件中使用package语句实现,package语句的语法格式如下:包名:必选,用于指定包的名称,包的名称必须为合

124、法的Java标识符。当包中还有子包时,可以使用“包1.包2.包n”进行指定,其中,包1为最外层的包,而包n则为最内层的包。package包名;课件制作人:XXX4.3.3使用包中的类类可以访问其所在包中的所有类,还可以使用其他包中的所有public类。访问其他包中的public类可以有以下两种方法。(1)使用长名引用包中的类使用长名引用包中的类比较简单,只需要在每个类名前面加上完整的包名即可。例如,创建Round类(保存在com.lzw包中)的对象并实例化该对象的代码如下:com.lzw.Roundround=newcom.lzw.Round();课件制作人:XXX使用包中的类(2)使用imp

125、ort语句引入包中的类由于采用使用长名引用包中的类的方法比较繁琐,所以Java提供了import语句来引入包中的类。import语句的基本语法格式如下:当存在多个包名时,各个包名之间使用“.”分隔,同时包名与类名之间也使用“.”分隔。*:表示包中所有的类。例如,引入com.lzw包中的Round类的代码如下:可以引入该包下的全部类:import包名1.包名2.类名*;importcom.lzw.Round;importcom.lzw.*;课件制作人:XXX4.4继承在面向对象程序设计中,继承是不可或缺的一部分。通过继承可以实现代码的重用,提高程序的可维护性。课件制作人:XXX4.4.2子类的创

126、建在类的声明中,可以通过使用关键字extends来显式地指明其父类。语法格式为:修饰符:可选,用于指定类的访问权限,可选值为public、abstract和final。子类名:必选,用于指定子类的名称,类名必须是合法的Java标识符。一般情况下,要求首字母大写。extends父类名:必选,用于指定要定义的子类继承于哪个父类。修饰符class子类名extends父类名课件制作人:XXX子类的创建例如定义一个Cattle类,该类继承于父类Animal,即Cattle类是Animal类的子类:abstractclassCattleextendsAnimal/此处省略了类体的代码课件制作人:XXX4.

127、4.3继承的使用原则子类可以继承父类中所有可被子类访问的成员变量和成员方法,但必须遵循以下原则:(1)子类能够继承父类中被声明为public和protected的成员变量和成员方法,但不能继承被声明为private的成员变量和成员方法;(2)子类能够继承在同一个包中的由默认修饰符修饰的成员变量和成员方法;(3)如果子类声明了一个与父类的成员变量同名的成员变量,则子类不能继承父类的成员变量,此时称子类的成员变量隐藏了父类的成员变量;(4)如果子类声明了一个与父类的成员方法同名的成员方法,则子类不能继承父类的成员方法,此时称子类的成员方法覆盖了父类的成员方法。课件制作人:XXX继承的使用原则【例4

128、-4】定义一个动物类Animal及它的子类Bird。课件制作人:XXX4.4.4使用this关键字当局部变量和成员变量的名字相同时,成员变量就会被隐藏,这时如果想在成员方法中使用成员变量,则必须使用关键字this。语法格式为:【例4-5】this.成员变量名this.成员方法名()课件制作人:XXX4.4.5 使用super关键字子类可以继承父类的非私有成员变量和成员方法(不是以private关键字修饰的),但是,如果子类中声明的成员变量与父类的成员变量同名,那么父类的成员变量将被隐藏。如果子类中声明的成员方法与父类的成员方法同名,并且参数个数、类型和顺序也相同,那么称子类的成员方法覆盖了父类

129、的成员方法。这时,如果想在子类中访问父类中被子类隐藏的成员方法或变量时,就可以使用super关键字。课件制作人:XXX使用super关键字super关键字主要有以下两种用途。(1)调用父类的构造方法(2)操作被隐藏的成员变量和被覆盖的成员方法课件制作人:XXX调用父类的构造方法子类可以调用父类的构造方法。但是必须在子类的构造方法中使用super关键字来调用。其语法格式如下:如果父类的构造方法中包括参数,则参数列表为必选项,用于指定父类构造方法的入口参数。例如下面的代码在Animal类中添加一个默认的构造方法和一个带参数的构造方法:super(参数列表);publicAnimal()public

130、Animal(StringstrSkin)skin=strSkin;课件制作人:XXX调用父类的构造方法这时,如果想在子类Bird中使用父类的带参数的构造方法,则需要在子类Bird的构造方法中通过以下代码进行调用:publicBird()super(羽毛);课件制作人:XXX操作被隐藏的成员变量和被覆盖的成员方法如果想在子类中操作父类中被隐藏的成员变量和被覆盖的成员方法,也可以使用super关键字。如果想在子类Bird的方法中改变父类Animal的成员变量skin的值可以使用以下代码:如果想在子类Bird的方法中使用父类Animal的成员方法move()可以使用以下代码:super.成员变量名

131、super.成员方法名(参数列表)super.skin=羽毛;super.move();课件制作人:XXX4.5多态多态是面向对象程序设计的重要部分,是面向对象的3个基本特性之一。在Java语言中,通常使用方法的重载(Overloading)和覆盖(Overriding)实现类的多态性。课件制作人:XXX4.5.1方法的重载方法的重载是指在一个类中,出现多个方法名相同,但参数个数或参数类型不同的方法,则称为方法的重载。Java在执行具有重载关系的方法时,将根据调用参数的个数和类型区分具体执行的是哪个方法。【例4-6】课件制作人:XXX4.5.1方法的重载方法的重载是指在一个类中,出现多个方法名

132、相同,但参数个数或参数类型不同的方法,则称为方法的重载。Java在执行具有重载关系的方法时,将根据调用参数的个数和类型区分具体执行的是哪个方法。重载的方法之间并不一定必须有联系,但是为了提高程序的可读性,一般只重载功能相似的方法。【例4-6】注意:在方法重载时,方法返回值的类型不能作为区分方法重载的标志。课件制作人:XXX4.5.3向上转型一个对象可以看做本类类型,也可以看做它的超类类型。取得一个对象的引用并将它看做超类的对象,称为向上转型。【例4-8】课件制作人:XXX4.6特殊类Java语言中还包含一些特殊的类定义方式,例如:n抽象类nfinal类n内部类它们都属于Java类的高级特性。课

133、件制作人:XXX4.6.1抽象类和抽象方法所谓抽象类就是只声明方法的存在而不去具体实现它的类。抽象类不能被实例化,也就是不能创建其对象。在定义抽象类时,要在关键字class前面加上关键字abstract。语法格式为:例如定义一个名称为Fruit的抽象类:abstractclass类名类体abstractclassFruit/定义抽象类publicStringcolor;/定义颜色成员变量publicFruit()/定义构造方法color=绿色;/对变量color进行初始化课件制作人:XXX抽象方法在抽象类中创建的、没有实现的、必须要子类重写的方法称为抽象方法。抽象方法只有方法的声明,而没有方法

134、的实现,用关键字abstract进行修饰。方法返回值类型:必选,用于指定方法的返回值类型,如果该方法没有返回值,可以使用关键字void进行标识。方法名:必选,用于指定抽象方法的名称。参数列表:可选,用于指定方法中所需的参数。当存在多个参数时,各参数之间应使用逗号分隔。在抽象类中添加一个抽象方法,可使用如下代码:abstract方法名(参数列表);publicabstractvoidharvest();/收获的方法课件制作人:XXX抽象方法包含一个或多个抽象方法的类必须被声明为抽象类。这是因为抽象方法没有定义方法的实现部分,如果不声明为抽象类,这个类将可以生成对象,这时当用户调用抽象方法时,程序

135、就不知道如何处理了。【例4-9】注意:抽象方法不能使用private或static关键字进行修饰。课件制作人:XXX4.4.2final类使用关键字final修饰的类称为final类,该类不能被继承,即不能有子类。有时为了程序的安全性,可以将一些重要的类声明为final类。例如,Java语言提供的System类和String类都是Final类。定义final类的语法格式为:finalclass类名类体课件制作人:XXX4.6.3内部类Java语言允许在类中定义内部类,内部类就是在其他类内部定义的子类。一般格式为:内部类有以下4种形式:n成员内部类n局部内部类n静态内部类n匿名内部类public

136、classZooclassWolf/内部类Wolf课件制作人:XXX成员内部类成员内部类和成员变量一样,属于类的全局成员。一般格式为:注意:成员变量id定义为公有属性public,但是内部类Inner不可以使用public修饰符,因为公共类的名称必须与类文件同名,所以每个Java类文件中只允许存在一个public公共类。publicclassSamplepublicintid;/成员变量classInner/成员内部类课件制作人:XXX成员内部类Inner内部类和变量id都被定义为Sample类的成员,但是Inner成员内部类的使用要比id成员变量复杂一些。一般格式为:只有创建了成员内部类的实

137、例,才能使用成员内部类的变量和方法。【例4-10】Samplesample=newSample();Sample.Innerinner=sample.newInner();课件制作人:XXX局部内部类局部内部类和局部变量一样,都是在方法内定义的,其有效范围只在方法内部有效。一般格式为:局部内部类可以访问它的创建类中的所有成员变量和成员方法,包括私有方法。【例4-11】publicvoidsell()classApple/局部内部类课件制作人:XXX静态内部类静态内部类和静态变量类似,它都使用static关键字修饰。所以在学习静态内部类之前,必须熟悉静态变量的使用。一般格式为:静态内部类可以在不

138、创建Sample类的情况下直接使用。【例4-12】publicclassSamplestaticclassApple/静态内部类课件制作人:XXX匿名类匿名类就是没有名称的内部类,它经常被应用于Swing程序设计中的事件监听处理。一般格式为:例如创建一个匿名的Apple类,可以使用如下代码:newClassName()publicclassSamplepublicstaticvoidmain(Stringargs)newApple()publicvoidintroduction()System.out.println(这是一个匿名类,但是谁也无法使用它。);课件制作人:XXX匿名类虽然成功创建

139、了一个Apple匿名类,但是正如它的introduction()方法所描述的那样,谁也无法使用它,这是因为没有一个对该类的引用。匿名类经常用来创建接口的唯一实现类,或者创建某个类的唯一子类。【例4-13】课件制作人:XXX4.7接口Java只支持单重继承,不支持多重继承,即一个类只能有一个父类。但是在实际应用中,又经常需要使用多重继承来解决问题。为了解决该问题,Java提供了接口来实现类的多重继承功能。课件制作人:XXX4.7.1定义接口Java语言使用关键字interface来定义一个接口。接口定义与类的定义类似,也是分为接口的声明的接口体,其中接口体由常量定义和方法定义两部分组成。语法格式

140、如下:修饰符interface接口名extends父接口名列表publicstaticfinal常量;publicabstract方法;课件制作人:XXX定义接口修饰符:可选,用于指定接口的访问权限,可选值为public。如果省略则使用默认的访问权限。接口名:必选,用于指定接口的名称,接口名必须是合法的Java标识符。一般情况下,要求首字母大写。extends父接口名列表:可选参数,用于指定要定义的接口继承于哪个父接口。当使用extends关键字时,父接口名为必选参数。方法:接口中的方法只有定义而没有被实现。课件制作人:XXX定义接口例如定义一个Calculate接口,在该接口中定义一个常量P

141、I和两个方法。publicinterfaceCalculatefinalfloatPI=3.14159f;floatgetArea(floatr);floatgetCircumference(floatr);课件制作人:XXX4.7.2实现接口接口可以被类实现也可以被其他接口继承。在类中实现接口可以使用关键字implements。语法格式为:修饰符:可选。类名:必选。extends父类名:可选参数implements接口列表:可选参数,用于指定该类实现哪些接口。当接口列表中存在多个接口名时,各个接口名之间使用逗号分隔。修饰符classextends父类名implements接口列表课件制作人:

142、XXX实现接口在类实现接口时,方法的名字、返回值类型、参数的个数及类型必须与接口中的完全一致,并且必须实现接口中的所有方法。例如创建实现Calculate接口的Circle类,可以使用如下代码:publicclassCireimplementsCalculate/实现计算圆面积的方法publicfloatgetArea(floatr)floatarea=PI*r*r;/计算圆面积并赋值给变量areareturnarea;/返回计算后的圆面积/实现计算圆周长的方法publicfloatgetCircumference(floatr)floatcircumference=2*PI*r;/计算圆周长

143、并赋值给变量circumferencereturncircumference;/返回计算后的圆周长课件制作人:XXX实现接口每个类只能实现单重继承,而实现接口时,一次则可以实现多个接口,每个接口间使用逗号“,”分隔。这时就可能出现常量或方法名冲突的情况,解决该问题时,如果常量冲突,则需要明确指定常量的接口,这可以通过“接口名.常量”实现。如果出现方法冲突时,则只要实现一个方法就可以了。【例4-14】JSP程序设计教程课件 制作人:XXXJava实用教程第5章集合课件制作人:XXX第4章面向对象基础5.1集合中主要接口的概述5.2Collection接口5.3List集合5.4Set集合5.5M

144、ap集合课件制作人:XXX5.2Collection接口Collection接口是List接口和Set接口的父接口,通常情况下不被直接使用,不过Collection接口定义了一些通用的方法,通过这些方法可以实现对集合的基本操作,因为List接口和Set接口实现了Collection接口,所以这些方法对List集合和Set集合是通用的。Collection接口定义的常用方法如下表所示:课件制作人:XXX方 法 名 称功 能 简 介add(E obj)将指定的对象添加到该集合中addAll(Collection col)将指定集合中的所有对象添加到该集合中remove(Object obj)将指定

145、的对象从该集合中移除。返回值为boolean型,如果存在指定的对象则返回true,否则返回falseremoveAll(Collection col)从该集合中移除同时包含在指定集合中的对象,与retainAll()方法正好相反。返回值为boolean型,如果存在符合移除条件的对象则返回true,否则返回falseretainAll(Collection col)仅保留该集合中同时包含在指定集合中的对象,与removeAll()方法正好相反。返回值为boolean型,如果存在符合移除条件的对象则返回true,否则返回falsecontains(Object obj)用来查看在该集合中是否存在指

146、定的对象。返回值为boolean型,如果存在则返回true,否则返回falsecontainsAll(Collection col)用来查看在该集合中是否存在指定集合中的所有对象。返回值为boolean型,如果存在则返回true,否则返回falseisEmpty()用来查看该集合是否为空。返回值为boolean型,如果在集合中未存放任何对象则返回true,否则返回falsesize()用来获得该集合中存放对象的个数。返回值为int型,为集合中存放对象的个数clear()移除该集合中的所有对象,清空该集合iterator()用来序列化该集合中的所有对象。返回值为Iterator型,通过返回的It

147、erator型实例可以遍历集合中的对象toArray()用来获得一个包含所有对象的Object型数组toArray(T t)用来获得一个包含所有对象的指定类型的数组equals(Object obj)用来查看指定的对象与该对象是否为同一个对象。返回值为boolean型,如果为同一个对象则返回true,否则返回false课件制作人:XXX5.2.1 addAll()方法addAll(Collection col)方法用来将指定集合中的所有对象添加到该集合中。如果对该集合进行了泛化,则要求指定集合中的所有对象都符合泛化类型,否则在编译程序时将抛出异常,入口参数中的“”就说明了这个问题,其中的E为用

148、来泛化的类型。【例5-1】 课件制作人:XXX5.2.2 removeAll()方法removeAll(Collectioncol)方法用来从该集合中移除同时包含在指定集合中的对象,与retainAll()方法正好相反。返回值为boolean型,如果存在符合移除条件的对象则返回true,否则返回false。【例5-2】课件制作人:XXX5.2.4 containsAll()方法containsAll(Collectioncol)方法用来查看在该集合中是否存在指定集合中的所有对象。返回值为boolean型,如果存在则返回true,否则返回false。【例5-4】课件制作人:XXX5.2.5 to

149、Array()方法toArray(Tt)方法用来获得一个包含所有对象的指定类型的数组。toArray(Tt)方法的入口参数必须为数组类型的实例,并且必须已经被初始化,它用来指定欲获得数组的类型,如果对调用toArray(Tt)方法的实例进行了泛化,还要求入口参数的类型必须符合泛化类型。【例5-5】课件制作人:XXX5.3List集合List包括List接口以及List接口的所有实现类。因为List接口实现了Collection接口,所以List接口拥有Collection接口提供的所有常用方法,又因为List是列表类型,所以List接口还提供了一些适合于自身的常用方法,如下表所示。课件制作人:

150、XXX方 法 名 称功 能 简 介add(int index, Object obj)用来向集合的指定索引位置添加对象,其他对象的索引位置相对后移一位。索引位置从0开始addAll(int, Collection coll)用来向集合的指定索引位置添加指定集合中的所有对象remove(int index)用来清除集合中指定索引位置的对象set(int index, Object obj)用来将集合中指定索引位置的对象修改为指定的对象get(int index)用来获得指定索引位置的对象indexOf(Object obj)用来获得指定对象的索引位置。当存在多个时,返回第一个的索引位置;当不存在

151、时,返回-1lastIndexOf(Object obj)用来获得指定对象的索引位置。当存在多个时,返回最后一个的索引位置;当不存在时,返回-1listIterator()用来获得一个包含所有对象的ListIterator型实例listIterator(int index)用来获得一个包含从指定索引位置到最后的ListIterator型实例subList(int fromIndex, int toIndex)通过截取从起始索引位置fromIndex(包含)到终止索引位置toIndex(不包含)的对象,重新生成一个List集合并返回课件制作人:XXXList集合List接口提供的适合于自身的常用

152、方法均与索引有关,这是因为List集合为列表类型,以线性方式存储对象,可以通过对象的索引操作对象。List接口的常用实现类有ArrayList和LinkedList,在使用List集合时,通常情况下声明为List类型,实例化时根据实际情况的需要,实例化为ArrayList或LinkedList,例如:Listl=newArrayList();/利用ArrayList类实例化List集合Listl2=newLinkedList();/利用LinkedList类实例化List集合课件制作人:XXXadd(intindex,Objectobj)方法和set(intindex,Objectobj)方法

153、在使用List集合时需要注意区分add(intindex,Objectobj)方法和set(intindex,Objectobj)方法,前者是向指定索引位置添加对象,而后者是替换指定索引位置的对象,索引值从0开始。【例5-6】课件制作人:XXXindexOf(Objectobj)方法和lastIndexOf(Objectobj)方法在使用List集合时需要注意区分indexOf(Objectobj)方法和lastIndexOf(Objectobj)方法,前者是获得指定对象的最小的索引位置,而后者是获得指定对象的最大的索引位置,前提条件是指定的对象在List集合中具有重复的对象,否则如果在Lis

154、t集合中有且仅有一个指定的对象,则通过这两个方法获得的索引位置是相同的。【例5-7】课件制作人:XXXsubList(intfromIndex,inttoIndex)方法使用subList(intfromIndex,inttoIndex)方法可以截取现有List集合中的部分对象,生成新的List集合。需要注意的是,新生成的集合中包含起始索引位置的对象,但是不包含终止索引位置的对象。【例5-8】课件制作人:XXX5.3.2使用ArrayList类ArrayList类实现了List接口,由ArrayList类实现的List集合采用数组结构保存对象。数组结构的优点是便于对集合进行快速的随机访问,如果

155、经常需要根据索引位置访问集合中的对象,使用由ArrayList类实现的List集合的效率较好。数组结构的缺点是向指定索引位置插入对象和删除指定索引位置对象的速度较慢。如果经常需要向List集合的指定索引位置插入对象,或者是删除List集合的指定索引位置的对象,使用由ArrayList类实现的List集合的效率较低,并且插入或删除对象的索引位置越小效率越低,原因是当向指定的索引位置插入对象时,会同时将指定索引位置及之后的所有对象相应地向后移动一位,如下所示课件制作人:XXX使用ArrayList类课件制作人:XXX使用ArrayList类当删除指定索引位置的对象时,会同时将指定索引位置之后的所有

156、对象相应地向前移动一位,如下图所示如果在指定的索引位置之后有大量的对象,将严重影响对集合的操作效率。课件制作人:XXX使用ArrayList类就是因为由ArrayList类实现的List集合在插入和删除对象时存在这样的缺点,在【例5-6】中才没有利用ArrayList类实例化List集合。【例5-9】课件制作人:XXX5.3.3使用LinkedList类LinkedList类实现了List接口,由LinkedList类实现的List集合采用链表结构保存对象。链表结构的优点是便于向集合中插入和删除对象,如果经常需要向集合中插入对象,或者从集合中删除对象,使用由LinkedList类实现的List

157、集合的效率较好。链表结构的缺点是随机访问对象的速度较慢,如果经常需要随机访问集合中的对象,使用由LinkedList类实现的List集合的效率则较低。由LinkedList类实现的List集合便于插入和删除对象的原因是当插入和删除对象时,只需要简单地修改链接位置,分别如下图所示,省去了移动对象的操作。课件制作人:XXX向由LinkedList类实现的List集合中插入对象从由LinkedList类实现的List集合中删除对象课件制作人:XXX使用LinkedList类LinkedList类还根据采用链表结构保存对象的特点,提供了几个专有的操作集合的方法,如下表所示。下面以操作由LinkedLi

158、st类实现的List集合的开头对象为例,介绍一下表5-3中几个方法的使用方法及实现的功能。【例5-10】方 法 名 称功 能 简 介addFirst(E obj)将指定对象插入到列表的开头addLast(E obj)将指定对象插入到列表的结尾getFirst()获得列表开头的对象getLast()获得列表结尾的对象removeFirst()移除列表开头的对象removeLast()移除列表结尾的对象课件制作人:XXX5.4Set集合Set集合为集类型,集是最简单的一种集合,存放于集中的对象不按特定方式排序,只是简单地把对象加入集合中,类似于向口袋里放东西。对集中存放的对象的访问和操作是通过对象

159、的引用进行的,所以在集中不能存放重复对象。Set集合包括Set接口以及Set接口的所有实现类。因为Set接口实现了Collection接口,所以Set接口拥有Collection接口提供的所有常用方法。课件制作人:XXX5.4.1使用HashSet类由HashSet类实现的Set集合的优点是能够快速定位集合中的元素。由HashSet类实现的Set集合中的对象必须是唯一的,所以需要添加到由HashSet类实现的Set集合中的对象,需要重新实现equals()方法,从而保证插入集合中对象的标识的唯一性。由HashSet类实现的Set集合按照哈希码排序,根据对象的哈希码确定对象的存储位置,所以需要添

160、加到由HashSet类实现的Set集合中的对象,还需要重新实现hashCode()方法,从而保证插入集合中的对象能够合理地分布在集合中,以便于快速定位集合中的对象。课件制作人:XXX使用HashSet类Set集合中的对象是无序的(这里所谓的无序,并不是完全无序,只是不像List集合那样按对象的插入顺序保存对象)例如下面的例子,遍历集合输出对象的顺序与向集合插入对象的顺序并不相同。【例5-11】课件制作人:XXX5.4.2使用TreeSet类TreeSet类不仅实现了Set接口,还实现了java.util.SortedSet接口,从而保证在遍历集合时按照递增的顺序获得对象。遍历对象时可能是按照自

161、然顺序递增排列,所以存入由TreeSet类实现的Set集合的对象时必须实现Comparable接口;也可能是按照指定比较器递增排列,即可以通过比较器对由TreeSet类实现的Set集合中的对象进行排序。TreeSet类实现了java.util.SortedSet接口,并增加了新的方法如下表所示。课件制作人:XXX使用TreeSet类方 法 名 称功 能 简 介comparator()获得对该集合采用的比较器。返回值为Comparator类型,如果未采用任何比较器则返回nullfirst()返回在集合中的排序位于第一的对象last()返回在集合中的排序位于最后的对象headSet(E toEle

162、ment)截取在集合中的排序位于对象toElement(不包含)之前的所有对象,重新生成一个Set集合并返回subSet(E fromElement, E toElement)截取在集合中的排序位于对象fromElement(包含)和对象toElement(不包含)之间的所有对象,重新生成一个Set集合并返回tailSet(E fromElement)截取在集合中的排序位于对象toElement(包含)之后的所有对象,重新生成一个Set集合并返回课件制作人:XXX使用TreeSet类下面将通过一个例子,详细介绍比较难于理解的headSet()、subSet()和tailSet()三个方法,以及

163、在使用时需要注意的事项。【例5-12】【例5-13】课件制作人:XXX5.5Map集合Map集合为映射类型,映射与集和列表有明显的区别,映射中的每个对象都是成对存在的。映射中存储的每个对象都有一个相应的键(key)对象,在检索对象时必须通过相应的键对象来获取值(value)对象,类似于在字典中查找单词一样,所以要求键对象必须是唯一的。键对象还决定了存储对象在映射中的存储位置,但并不是键对象本身决定的,需要通过一种散列技术进行处理,从而产生一个被称作散列码的整数值,散列码通常用作一个偏置量,该偏置量是相对于分配给映射的内存区域的起始位置的,由此来确定存储对象在映射中的存储位置。理想情况下,通过散

164、列技术得到的散列码应该是在给定范围内均匀分布的整数值,并且每个键对象都应得到不同的散列码。课件制作人:XXX5.5.1Map的用法Map包括Map接口以及Map接口的所有实现类。由Map接口定义的常用方法如下表所示。方 法 名 称功 能 简 介put(K key, V value)向集合中添加指定的键值映射关系putAll(Map t)将指定集合中的所有键值映射关系添加到该集合中containsKey(Object key)如果存在指定键的映射关系,则返回true;否则返回falsecontainsValue(Object value)如果存在指定值的映射关系,则返回true;否则返回fals

165、eget(Object key)如果存在指定的键对象,则返回与该键对象对应的值对象;否则返回nullkeySet()将该集合中的所有键对象以Set集合的形式返回values()将该集合中的所有值对象以Collection集合的形式返回remove(Object key)如果存在指定的键对象,则移除该键对象的映射关系,并返回与该键对象对应的值对象;否则返回nullclear()移除集合中所有的映射关系isEmpty()查看集合中是否包含键值映射关系,如果包含则返回true;否则返回falsesize()查看集合中包含键值映射关系的个数,返回值为int型equals(Object obj)用来查看

166、指定的对象与该对象是否为同一个对象。返回值为boolean型,如果为同一个对象则返回true,否则返回false课件制作人:XXXMap的用法Map接口的常用实现类有HashMap和TreeMap,HashMap通过哈希码对其内部的映射关系进行快速查找,而TreeMap中的映射关系存在一定的顺序,如果希望在遍历集合时是有序的,则应该使用由TreeMap类实现的Map集合,否则建议使用由HashMap类实现的Map集合,因为由HashMap类实现的Map集合对于添加和删除映射关系更高效。Map集合允许值对象为null,并且没有个数限制,所以当get()方法的返回值为null时,可能有两种情况,一

167、种是在集合中没有该键对象,另一种是该键对象没有映射任何值对象,即值对象为null。因此,在Map集合中不应该利用get()方法来判断是否存在某个键,而应该利用containsKey()方法来判断。【例5-14】课件制作人:XXX5.5.2使用HashMap类HashMap类实现了Map接口,由HashMap类实现的Map集合,允许以null作为键对象,但是因为键对象不可以重复,所以这样的键对象只能有一个。如果经常需要添加、删除和定位映射关系,建议利用HashMap类实现Map集合,不过在遍历集合时,得到的映射关系是无序的。课件制作人:XXX使用HashMap类在使用由HashMap类实现的Ma

168、p集合时,需要重写作为主键对象类的hashCode()方法,在重写hashCode()方法时,有以下两条基本原则:(1)不唯一原则:不必为每个对象生成一个唯一的哈希码,只要通过hashCode方法生成的哈希码能够利用get()方法得到利用put()方法添加的映射关系就可以;(2)分散原则:生成哈希码的算法应尽量使哈希码的值分散一些,不要很多哈希码值都集中在一个范围内,这样有利于提高由HashMap类实现的Map集合的性能。【例5-15】课件制作人:XXX5.5.3使用TreeMap类TreeMap类不仅实现了Map接口,还实现了Map接口的子接口java.util.SortedMap。由Tre

169、eMap类实现的Map集合,不允许键对象为null,因为集合中的映射关系是根据键对象按照一定顺序排列的,TreeMap类通过实现SortedMap接口得到的方法如下表所示。课件制作人:XXX方 法 名 称功 能 简 介comparator()获得对该集合采用的比较器。返回值为Comparator类型,如果未采用任何比较器则返回nullfirstKey()返回在集合中的排序位于第一位的键对象lastKey()返回在集合中的排序位于最后一位的键对象headMap(K toKey)截取在集合中的排序位于键对象toKey(不包含)之前的所有映射关系,重新生成一个SortedMap集合并返回subMap

170、(K fromKey, K toKey)截取在集合中的排序位于键对象fromKey(包含)和toKey(不包含)之间的所有映射关系,重新生成一个SortedMap集合并返回tailMap(K fromKey)截取在集合中的排序位于键对象fromKey(包含)之后的所有映射关系,重新生成一个SortedMap集合并返回课件制作人:XXX使用TreeMap类在添加、删除和定位映射关系上,TreeMap类要比HashMap类的性能差一些,但是其中的映射关系具有一定的顺序,如果不需要一个有序的集合,则建议使用HashMap类;如果需要进行有序的遍历输出,则建议使用TreeMap类,在这种情况下,可以先

171、使用由HashMap类实现的Map集合,在需要顺序输出时,再利用现有的HashMap类的实例,创建一个具有完全相同映射关系的TreeMap类型的实例。【例5-16】JSP程序设计教程课件 制作人:XXXJava实用教程第6章Java输入与输出(I/O)课件制作人:XXX第6章Java输入与输出(I/O)6.1File类6.2流6.3字节流6.4字符流6.5RandomAccessFile类6.6过滤器流6.7对象序列化(objectcserialization)6.8Scanner类课件制作人:XXX6.1File类File类是一个与流无关的类。File类的对象可以获取文件及其文件所在的目录、

172、文件的长度等信息。创建一个File对象的常用构造方法有3种:(1)File(Stringpathname)(2)File(Stringpath,Stringfilename)(3)File(Filefile,Stringfilename)课件制作人:XXXFile类(1)File(Stringpathname)该构造方法通过指定的文件路径字符串来创建一个新File实例对象。语法:pathname:文件路径字符串,包括文件名称。就是将一个代表路径的字符串转换为抽象的路径。newFile(filename);课件制作人:XXXFile类(2)File(Stringpath,Stringfilena

173、me)该构造方法根据指定的父路径字符串和子路径字符串(包括文件名称)创建File类的实例对象。语法:path:父路径字符串。filename:子路径字符串,不能为空。newFile(path,filename);课件制作人:XXXFile类(3)File(Filefile,Stringfilename)该构造方法根据指定的File类的父路径和字符串类型的子路径(包括文件名称)创建File类的实例对象。语法:file:是父路径对象。filename:子路径字符串。File类包含了文件和文件夹的多种属性和操作方法。常用的方法如下表所示。【例6-1】newFile(file,filename);课件

174、制作人:XXX方 法 名 称功 能 描 述getName()获取文件的名字getParent()获取文件的父路径字符串getPath()获取文件的相对路径字符串getAbsolutePath()获取文件的绝对路径字符串exists()判断文件或文件夹是否存在canRead()判断文件是否可读的isFile()判断文件是否是一个正常的文件,而不是目录canWrite()判断文件是否可被写入idDirectory()判断是不是文件夹类型isAbsolute()判断是不是绝对路径isHidden()判断文件是否是隐藏文件delete()删除文件或文件夹,如果删除成功返回结果为truemkdir()创

175、建文件夹,如果创建成功返回结果为truemkdirs()创建路径中包含的所有父文件夹和子文件夹,如果所有父文件夹和子文件夹都成功创建,返回结果为truecreateNewFile()创建一个新文件length()获取文件的长度lastModified()获取文件的最后修改日期课件制作人:XXX6.2流流(stream)是一组有序的数据序列。根据操作的类型,分为输入流和输出流两种。输入流的指向称为源,程序从指向源的输入流中读取数据。当程序需要读取数据时,就会开启一个通向数据源的流,这个数据源可以是文件、内存或是网络连接。而输出流的指向是字节要去的目的地,程序通过向输出流中写入数据把信息传递到目的

176、地。当程序需要写入数据时,就会开启一个通向目的地的流。课件制作人:XXX6.2.2输入输出流输入输出流一般分为4种:n字节输入流n字节输出流n字符输入流n字符输出流课件制作人:XXX字节输入流InputStream类是字节输入流的抽象类,它是所有字节输入流的父类,其各种子类实现了不同的数据输入流。这些字节输入流的继承关系如下图所示。课件制作人:XXX字节输出流OutputStream类是字节输出流的抽象类,它是所有字节输出流的父类,其子类实现了不同数据的输出流。继承关系如下图所示。课件制作人:XXX字符输入流Reader类是字符输入流的抽象类,所有字符输入流的实现都是它的子类。Java中字符输

177、入流的继承关系如下图所示。课件制作人:XXX字符输出流Writer类是字符输出流的抽象类,所有字符输出流的实现都是它的子类。Java中字符输出流的继承关系如下图所示。课件制作人:XXX6.3字节流字节流是以字节为单位来处理数据的,由于字节流不会对数据做任何转换,因此用来处理二进制的数据。课件制作人:XXX6.3.1InputStream类与OutputStream类InputStream类是所有字节输入流的父类,它定义了操作输入流的各种方法。常用方法如下表所示。方 法 名 称功 能 描 述available()返回当前输入流的数据读取方法可以读取的有效字节数量read(byte bytes)从

178、输入数据流中读取字节并存入数组b中read(byte bytes,int off,int len)从输入数据流读取len个字节,并存入数组bytes中reset()将当前输入流重新定位到最后一次调用mark() 方法时的位置mark(int readlimit)在输入数据流中加入标记markSupported()测试输入流中是否支持标记close()关闭当前输入流,并释放任何与之关联的系统资源Abasract read()从当前数据流中读取一个字节。若已到达流结尾,则返回-1课件制作人:XXXInputStream类与OutputStream类OutputStream类是所有字节输出流的父类,

179、它定义了输出流的各种操作方法。常用的方法如下表所示。方 法 名 称功 能 描 述available()返回当前输入流的数据读取方法可以读取的有效字节数量read(byte bytes)从输入数据流中读取字节并存入数组b中read(byte bytes,int off,int len)从输入数据流读取len个字节,并存入数组bytes中reset()将当前输入流重新定位到最后一次调用mark() 方法时的位置mark(int readlimit)在输入数据流中加入标记markSupported()测试输入流中是否支持标记close()关闭当前输入流,并释放任何与之关联的系统资源Abasract

180、read()从当前数据流中读取一个字节。若已到达流结尾,则返回-1课件制作人:XXX6.3.2FileInputStream类FileInputStream类是InputStream类的子类。它实现了文件的读取,是文件字节输入流。该类适用于比较简单的文件读取,该类的所有方法都是从InputStream类继承并重写的。创建文件字节输入流常用的构造方法有两种:nFileInputStream(StringfilePath)nFileInputStream(Filefile)课件制作人:XXXFileInputStream类(1)FileInputStream(StringfilePath)该构造方

181、法根据指定的文件名称和路径,创建FileInputStream类的实例对象。语法:filePath:文件的绝对路径或相对路径。newFileInputStream(filePath);课件制作人:XXXFileInputStream类(2)FileInputStream(Filefile)该构造方法使用File类型的文件对象创建FileInputStream类的实例对象。语法:file:File文件类型的实例对象。【例6-2】newFileInputStream(file);课件制作人:XXX6.3.3FileOutputStream类FileOutputStream类是OutputStrea

182、m类的子类。它实现了文件的写入,能够以字节形式写入文件中,该类的所有方法都是从OutputStream类继承并重写的。创建文件字节输出流常用的构造方法有两种:nFileOutputStream(StringfilePath)nFileOutputStream(Filefile)课件制作人:XXXFileOutputStream类(1)FileOutputStream(StringfilePath)该构造方法根据指定的文件名称和路径,创建关联该文件的FileOutputStream类的实例对象。语法:filePath:文件的绝对路径或相对路径。newFileOutputStream(filePa

183、th);课件制作人:XXXFileOutputStream类(2)FileOutputStream(Filefile)该构造方法使用File类型的文件对象,创建与该文件关联的FileOutputStream类的实例对象。语法:file:File文件类型的实例对象。在file后面,加true会对原有内容进行追加,不加true会将原有内容覆盖。【例6-3】newFileOutputStream(file);课件制作人:XXX6.4字符流字符流(charactercstreams)用于处理字符数据的读取和写入,它以字符为单位。Reader类和Writer类是字符流的抽象类,它们定义了字符流读取和写入

184、的基本方法,各个子类会依其特点实现或覆盖这些方法。课件制作人:XXX6.4.1Reader类与Writer类Reader类是所有字符输入流的父类,它定义了操作字符输入流的各种方法。常用方法如下表所示。方法名称功 能 描 述read()读入一个字符。若已读到流结尾,则返回值为1read(char)读取一些字符到char数组内,并返回所读入的字符的数量。若已到达流结尾,则返回-1reset()将当前输入流重新定位到最后一次调用mark() 方法时的位置skip(long n)跳过参数n指定的字符数量,并返回所跳过字符的数量close()关闭该流并释放与之关联的所有资源。在关闭该流后,再调用 rea

185、d()、ready()、mark()、reset() 或 skip() 将抛出异常课件制作人:XXXReader类与Writer类Writer类是所有字符输出流的父类,它定义了操作输出流的各种方法。常用方法如下表所示。方 法 名 称功 能 描 述write(int c)将字符c写入输出流write(String str)将字符串str写入输出流write(char cbuf)将字符数组的数据写入到字符输出流flush()刷新当前输出流,并强制写入所有缓冲的字节数据close()向输出流写入缓冲区的数据,然后关闭当前输出流,并释放所有与当前输出流有关的系统资源课件制作人:XXX6.4.2Inpu

186、tStreamReader类InputStreamReader是字节流通向字符流的桥梁。它可以根据指定的编码方式,将字节输入流转换为字符输入流。创建字符输入流常用的构造方法有两种:nInputStreamReader(InputStreamin)nInputStreamReader(InputStreamin,Stringcname)课件制作人:XXXInputStreamReader类(1)InputStreamReader(InputStreamin)该构造方法使用默认字符集创建InputStreamReader类的实例对象。语法如下:in:字节流类的实例对象。newInputStream

187、Reader(in);课件制作人:XXXInputStreamReader类(2)InputStreamReader(InputStreamin,Stringcname)该构造方法使用已命名的字符编码方式创建InputStreamReader类的实例对象。语法如下:cname:使用的编码方式名。InputStreamReader类常用的方法如下表所示。newInputStreamReader(in,cname);课件制作人:XXXInputStreamReader类【例6-4】方 法 名 称功 能 描 述close()关闭流read()读取单个字符read(char cb, int off,

188、int len)将字符读入数组中的某一部分getEncoding()返回此流使用的字符编码的名称ready()报告此流是否已准备读课件制作人:XXX6.4.3OutputStreamWriter类OutputStreamWriter是字节流通向字符流的桥梁。写出字节,并根据指定的编码方式,将之转换为字符流。创建字符输出流常用的构造方法有两种。nOutputStreamWriter(OutputStreamout)nOutputStreamWriter(OutputStreamout,Stringcname)课件制作人:XXXOutputStreamWriter类(1)OutputStreamW

189、riter(OutputStreamout)该构造方法使用默认字符集创建OutputStreamWriter类的实例对象。语法如下:out:字节流类的实例对象。newOutputStreamReader(out);课件制作人:XXXOutputStreamWriter类(2)OutputStreamWriter(OutputStreamout,Stringcname)该构造方法使用已命名的字符编码方式创建OutputStreamWriter类的实例对象。语法如下:cname:使用的编码方式名。OutputStreamReader类常用的方法如下表所示:newOutputStreamWriter

190、(out,cname);课件制作人:XXXOutputStreamWriter类【例6-5】方 法 名 称功 能 描 述close()关闭流,但要先刷新flush()刷新流的缓冲write(int char)写入单个字符write(String str, int off, int len)写入字符串的某一部分write(char cb, int off, int len)写入字符数组的某一部分课件制作人:XXX6.4.4FileReader类FileReader类是Reader类的子类,它实现了从文件中读出字符数据,是文件字符输入流。该类的所有方法都是从Reader类中继承来的。FileRea

191、der类的常用构造方法有两种:nFileReader(StringfilePath)nFileReader(Filefile)课件制作人:XXXFileReader类(1)FileReader(StringfilePath)该构造方法根据指定的文件名称和路径,创建FileReader类的实例对象。语法如下:filePath:文件的绝对路径或相对路径。newFileReader(filePath);课件制作人:XXXFileReader类(2)FileReader(Filefile)该构造方法使用File类型的文件对象创建FileReader类的实例对象。语法如下:file:File文件类型的实

192、例对象。newFileReader(file);课件制作人:XXXFileReader类例如,利用FileReader读取文件“Example5-1.txt”的内容,输出到控制台上程序代码为:tryFilef=newFile(C:,Example5-1.txt);FileReaderfr=newFileReader(f);/创建文件字符输入流chardata=newchar512;intrs=0;while(rs=fr.read(data)0)/在循环中读取数据Stringstr=newString(data,0,rs);System.out.println(str);catch(Except

193、ione)e.printStackTrace();课件制作人:XXX6.4.5FileWriter类FileWriter类是Writer类的子类,它实现了将字符数据写入文件中,是文件字符输出流。该类的所有方法都是从Writer类中继承来的。FileWriter类的常用构造方法有两种:nFileWriter(StringfilePath)nFileWriter(Filefile)课件制作人:XXXFileWriter类(1)FileWriter(StringfilePath)该构造方法根据指定的文件名称和路径,创建关联该文件的FileWriter类的实例对象。语法如下:newFileWriter

194、(filePath);课件制作人:XXXFileWriter类(2)FileWriter(Filefile)该构造方法使用File类型的文件对象,创建与该文件关联的FileWriter类的实例对象。语法如下:newFileWriter(file);课件制作人:XXXFileWriter类例如,“Example5-1.txt”的内容复制到文件“Example6.txt”中。具体代码为:tryFilef=newFile(C:,Example6.txt);if(!f.exists()/如果文件不存在f.createNewFile();/创建新文件FileReaderfr=newFileReader(

195、C:Example5-1.txt);/创建文件字符输入流FileWriterfWriter=newFileWriter(f);/创建文件字符输出流intis;while(is=fr.read()!=-1)fWriter.write(is);/将数据写入输出流fr.close();fWriter.close();catch(Exceptione)e.printStackTrace();课件制作人:XXX6.4.6BufferedReader类BufferedReader类是Reader类的子类,使用该类可以以行为单位读取数据。BufferedReader类的主要构造方法为:该构造方法使用Read

196、er类的对象,创建一个BufferReader对象。语法如下:newBufferedReader(in);BufferedReader(Readerin)课件制作人:XXXBufferedReader类BufferedReader类中提供了一个ReaderLine()方法,Reader类中没有此方法,该方法能够读取文本行。例如:FileReaderfr;tryfr=newFileReader(C:Example6.txt);BufferedReaderbr=newBufferedReader(fr);Stringaline;while(aline=br.readLine()!=null)/按行

197、读取文本Stringstr=newString(aline);fr.close();br.close();catch(Exceptione)e.printStackTrace();课件制作人:XXX6.4.7BufferedWriter类BufferedWriter类是Writer类的子类,该类可以以行为单位写入数据。BufferedWriter类常用的构造方法为:该构造方法使用Writer类的对象,来创建一个BufferWriter对象。语法如下:newBufferedReader(out);BufferedWriter(Writerout)课件制作人:XXXBufferedWriter类B

198、ufferedWriter类提供了一个newLine()方法,Writer类中没有此方法。该方法是换行标记。例如:【例6-6】Filefile=newFile(C:,Example6.txt);FileWriterfos;tryfos=newFileWriter(file,true);BufferedWriterbw=newBufferedWriter(fos);bw.write(Example);bw.newLine();bw.write(Example);bw.close();catch(IOExceptione)e.printStackTrace();课件制作人:XXX6.4.8Prin

199、tStream类PrintStream是打印输出流,它可以直接输出各种类型的数据。创建打印输出流常用的构造方法为:该构造方法使用OutputStream类的对象,创建一个PrintStream对象。语法如下:newPrintStream(out);PrintStream(OutputStreamout)课件制作人:XXXPrintStream类PrintStream类常用的方法如下表所示。【例6-7】方 法 名 称功 能 描 述print(String str)打印字符串print(char ch)打印一个字符数组print(object obj)打印一个对象println(String st

200、r)打印一个字符串并结束该行println(char ch)打印一个字符数组并结束该行println(object obj)打印一个对象并结束该行课件制作人:XXX6.4.9PrintWriter类PrintWriter是打印输出流,该流把Java语言的内构类型以字符表示形式送到相应的输出流中,可以以文本的形式浏览。创建该打印输出流常用的构造方法有两种。nPrintWriter(Writerout)nPrintWriter(OutputStreamout)课件制作人:XXX6.4.9PrintWriter类(1)PrintWriter(Writerout)该构造方法使用Writer类的对象,创

201、建一个PrintWriter对象。语法:(2)PrintWriter(OutputStreamout)该构造方法使用OutputStream类的对象,创建一个PrintWriter对象。语法:PrintWriter类常用的方法如下表所示。newPrintWriter(out);newPrintWriter(out);课件制作人:XXXPrintWriter类方 法 名 称功 能 描 述print(String str)将字符串型数据写至输出流print(int i)将整型数据写至输出流flush()强制性地将缓冲区中的数据写至输出流println(String str)将字符串和换行符写至输出

202、流println(int i)将整型数据和换行符写至输出流println()将换行符写至输出流课件制作人:XXXPrintWriter类使用PrintWriter实现文件的复制执行过程为:Filefilein=newFile(C:,Example6.txt);Filefileout=newFile(C:,Example7.txt);try/创建一个BufferedReader对象BufferedReaderbr=newBufferedReader(newFileReader(filein);/创建一个PrintWiter对象PrintWriterpw=newPrintWriter(newFil

203、eWriter(fileout);intb;/读出文件“Example6.txt”中的数据while(b=br.read()!=-1)pw.println(b);/写入文件中br.close();/关闭流pw.close();/关闭流catch(Exceptione)e.printStackTrace();课件制作人:XXX6.4.10System.in获取用户输入System类中用于获取用户输入流的语法为:in:是静态变量,类型是InputStream。Java实现键盘输入的一般过程为:【例6-8】InputStreamReaderisr=newInputStreamReader(Syste

204、m.in);BufferedReaderbr=newBufferedReader(isr);tryStringstr=br.readLine();br.close();catch(IOExceptione)e.printStackTrace();System.in课件制作人:XXX6.5RandomAccessFile类使用RandomAccessFile类可以读取任意位置数据的文件。RandomAccessFile类既不是输入流类的子类,也不是输出流类的子类。RandomAccessFile类常用的构造方法有两种。nRandomAccessFile(Stringname,Stringmode

205、)nRandomAccessFile(Filefile,Stringmode)课件制作人:XXXRandomAccessFile类(1)RandomAccessFile(Stringname,Stringmode)语法如下:name:和系统相关的文件名。mode:用来决定创建的流对文件的访问权利,它可以是r、rw、rws或rwd,r代表只读,rw代表可读写,rws代表同步写入,rwd代表将更新同步写入。newRandomAccessFile(name,mode);课件制作人:XXXRandomAccessFile类(2)RandomAccessFile(Filefile,Stringmode)

206、语法如下:file:一个File类的对象。RandomAccessFile类常用的方法如下表所示:newRandomAccessFile(file,mode);课件制作人:XXXRandomAccessFile类方 法 名 称功 能 描 述length()获取文件的长度seek(long pos)设置文件指针位置readByte()从文件中读取一个字节readChar()从文件中读取一个字符readInt()从文件中读取一个int值readLine()从文件中读取一个文本行readBoolean()从文件中读取一个布尔值readUTF()从文件中读取一个UTF字符串write(byte byt

207、es)把bytes.length个字节写到文件writeInt(int v)向文件中写入一个int值writeChars(String str)向文件中写入一个作为字符数据的字符串writeUTF(String str)向文件中写入一个UTF字符串close()关闭文件课件制作人:XXXRandomAccessFile类利用上述方法显示文件本身源代码的执行过程如下:【例6-9】tryFilef=newFile(C:,Example8.txt);RandomAccessFileraf=newRandomAccessFile(f,rw);/创建随机访问文件为读写longfilepoint=0;/定

208、义文件总长度变量longfilel=raf.length();/获取文件的长度while(filepointfilel)Stringstr=raf.readLine();/从文件中读取数据System.out.println(str);filepoint=raf.getFilePointer();raf.close();catch(Exceptione)e.printStackTrace();课件制作人:XXX6.6过滤器流过滤器流(FilterStream)是为某种目的过滤字节或字符的数据流。基本输入流提供的读取方法,只能用来读取字节或字符。而过滤器流能够读取整数值、双精度值或字符串。但需要

209、一个过滤器类来包装输入流。DataInputStream和DataOutputStream类分别是FilterInputStream和FilterOutputStream类的子类。它们分别实现了DataInput和DataOutput接口,该接口中定义了独立于具体机器的带格式的读写操作,从而可以实现对Java中的不同基本类型数据的读写。课件制作人:XXX过滤器流例如,从文件中读取数据。可以先创建一个FileInputStream类的对象,然后把该类传递给一个DataInputStream的构造方法。fis=newFileInputStream(Example.txt);DataInputStr

210、eamdis=newDataInputStream(fis);inti=dis.readInt();dis.close();课件制作人:XXX过滤器流再例如,把数据写入文件。可以先创建一个FileOutputStream类的对象,然后把该类传递给一个DataOutputStream的构造方法。FileOutputStreamfos=newFileOutputStream(Example.txt);DataOutputStreamdos=newDataOutputStream(fos);dos.writeBytes(Example);dos.close();课件制作人:XXX6.7对象序列化(o

211、bjectcserialization)使用对象输入输出流实现对象序列化可以直接存取对象。将对象存入一个流称为序列化。而从一个流将对象读出称为反序列化。课件制作人:XXX6.7.1ObjectInput与ObjectOutputObjectInput接口与ObjectOutput接口分别继承了DataInput接口和DataOutput接口,提供了对基本数据类型和对象序列化的方法。使用对象序列化功能可以非常方便地将对象写入输出流,或者从输入流读取对象。ObjectInput接口与ObjectOutput接口中定义的对象反序列化和序列化方法如下。课件制作人:XXXObjectInput与Obje

212、ctOutput(1)readObject()所谓反序列化就是从输入流中获取序列化的对象数据,用这些数据生成新的Java对象。该方法定义在ObjectInput接口中,由ObjectInputStream类实现。语法如下:object:Java对象。注意:使用readObject()方法获取的序列化对象是Object类型的,必须通过强行类型转换才能使用。Objectobject=readObject()课件制作人:XXXObjectInput与ObjectOutput(2)writeObject()序列化就是将对象写入到输出流,这个输出流可以是文件输出流、网络输出流以及其他数据输出流。该方法定

213、义在ObjectOutput接口中,由ObjectOutputStream类实现。语法:object:将要序列化的对象。注意:被序列化的对象必须实现java.io.Serializable接口,否则不能实现序列化。writeObject(object);课件制作人:XXX6.7.2ObjectInputStream与ObjectOutputStreamJava提供了ObjectInputStream和ObjectOutputStream类读取和保存对象,它们分别是对象输入流和对象输出流。ObjectInputStream类和ObjectOutputStream类是InputStream类和Ou

214、tputStream类的子类,继承了它们所有的方法。n创建ObjectInputStream类的构造方法为:n当准备从读取一个对象到程序中时,可以用ObjectInputStream类创建对象输入流。语法如下:ObjectInputStream(InputStreamin)newObjectInputStream(in);课件制作人:XXXObjectInputStream与ObjectOutputStreamnObjectInputStream类读取基本数据类型的方法为:对象输入流使用该方法读取一个对象到程序中。例如:n创建ObjectOutputStream类的构造方法为:readObje

215、ct()FileInputStreamfis=newFileInputStream(Example.txt);ObjectInputStreamois=newObjectInputStream(fis);ois.readObject();ois.close();ObjectOutputStream(OutputStreamout)课件制作人:XXXObjectInputStream与ObjectOutputStreamn当准备将一个对象写入到输出流(即序列化),可以用ObjectOutputStream类创建对象输出流。语法如下:nObjectOutputStream类写入基本数据类型方法为:

216、对象输出流使用该方法将对象写入到文件中。例如:【例6-10】FileOutputStreamfos=newFileOutputStream(Example.txt);ObjectOutputStreamobs=newObjectOutputStream(fos);obs.writeObject(Example);obs.close();newObjectOutputStream(out);WriteObject()课件制作人:XXX6.8Scanner类Scanner是JDK1.5新增的一个类,是java.util包中的类。该类用来实现用户的输入,是一种只要有控制台就能实现输入操作的类。创建S

217、canner类常见的构造方法有两种。(1)Scanner(InputStreamin)语法如下:newScanner(in);课件制作人:XXXScanner类(2)Scanner(Filefile)语法如下:通过控制台进行输入,首先要创建一个Scanner对象。例如:【例6-11】Scannersc=newScanner(System.in);sc.next();sc.close();newScanner(file);JSP程序设计教程课件 制作人:XXXJava实用教程第7章多线程与异常处理课件制作人:XXX第7章多线程与异常处理7.1线程概述7.2线程的创建7.3线程的生命周期7.4线程

218、的优先级7.5线程的控制7.6线程的同步7.7线程通信7.8多线程产生死锁7.9异常课件制作人:XXX7.2线程的创建在Java语言中,线程也是一种对象,但并非任何对象都可以成为线程,只有实现Runnable接口或继承了Thread类的对象才能成为线程。课件制作人:XXXThread类Thread类中的主要的方法包括:nstart()方法ninterrupt()方法njoin()方法nrun()方法。其中start()方法与run()方法最为常用,start()方法用于启动线程,run()方法为线程的主体方法,可以根据需要重写run()方法。课件制作人:XXXThread类Thread类有4个

219、最常用构造方法。(1)默认构造方法默认的构造方法,没有参数列表。语法格式为:(2)基于Runnable对象的构造方法该构造方法包含了Runnable类型的参数,它是实现Runnable接口的类的实例对象,基于该构造方法创建的线程对象,将线程的业务逻辑交由参数所传递的Runnable对象去实现。语法格式为:simple:实现Runnable接口的对象Threadthread=newThread();Threadthread=newThread(Runnablesimple);课件制作人:XXXThread类(3)指定线程名称的构造方法该构造方法包含了String类型的参数,这个参数将作为新创建的

220、线程对象的名称。语法格式为:(4)基于Runnable对象并指定线程名称的构造方法该构造方法接收Runnable对象和线程名称的字符串。语法格式为:simple:实现Runnable接口的对象。name:线程名称。Threadthread=newThread(ThreadName);Threadthread=newThread(Runnablesimple,Stringname);课件制作人:XXXRunnable接口实现Runnable接口的类就可以成为线程,Thread类就是因为实现了Runnable接口所以才具有了线程的功能。Runnable接口只有一个方法就是run()方法,实现Run

221、nable()接口后必须实现run()方法。课件制作人:XXX7.2.2继承Thread类在Java语言中要实现线程功能,可以继承java.lang.Thread类,这个类已经具备了创建和运行线程的所有必要架构,通过重写Thread类中run()方法,以实现用户所需要的功能,实例化自定义的Thread类,使用start()方法启动线程。【例7-1】课件制作人:XXX7.2.3实现Runnable接口从本质上讲,Runnable是Java语言中用以实现线程的接口,任何实现线程功能的类都必须实现这个接口。Thread类就是因为实现了Runnable接口,所以继承它的类才具有了相应的线程功能。课件制

222、作人:XXX实现Runnable接口虽然可以使用继承Thread类的方式实现线程,但是由于在Java语言中,只能继承一个类,如果用户定义的类已经继承了其他类,就无法再继承Thread类,也就无法使用线程,于是Java语言为用户提供了一个接口,java.lang.Runnable,实现Runnable这个接口与继承Thread类具有相同的效果,通过实现这个接口就可以使用线程。Runnable接口中定义了一个run()方法,在实例化一个Thread对象时,可以传入一个实现Runnable接口的对象作为参数,Thread类会调用Runnable对象的run()方法,继而执行run()方法中的内容。【

223、例7-2】课件制作人:XXX7.3线程的生命周期线程主要有以下状态:n创建n可执行n非可执行n消亡课件制作人:XXX创建当实例化一个Thread对象并执行start()方法后,线程进入“可执行”状态,开始执行,虽然多线程给用户一种同时执行的感觉,但事实上在同一时间点上,只有一个线程在执行,只是线程之间转换的动作很快,所以看起来好像同时在执行一样。课件制作人:XXX可执行当线程启用start()方法后,进入“可执行”状态,执行用户覆写的run()方法。一个线程进入“可执行”状态下,并不代表它可以一直执行到run()结束为止,事实上它只是加入此应用程序执行安排的队列中,也就是说,这个线程加入了进程

224、的线程执行队列中,对于大多数计算机而言,只有一个处理器,无法使多个线程同时执行,这时需要合理安排线程执行计划,让那些处于“可执行”状态下的线程合理分享CPU资源。所以,一个处在“可执行”状态下的线程,实际上可能正在等待取得CPU时间,也就是等候执行权,在何时给予线程执行权,则由Java虚拟机和线程的优先级来决定。课件制作人:XXX非可执行在“可执行”状态下,线程可能被执行完毕,也可能没有执行完毕,处于等待执行权的队列中,当使线程离开“可执行”状态下的等待队列时,线程进入“非可执行”状态。可以使用Thread类中的wait()、sleep()方法使线程进入“非可执行”状态。课件制作人:XXX消亡

225、当run()方法执行完毕后,线程自动消亡,当Thread类调用start()方法时,Java虚拟机自动调用它的run()方法,而当run()方法结束时,该Thread会自动终止。以前Thread类中存在一个停止线程的stop()方法,不过它现在被废弃了,因为调用这个方法,很容易使程序进入不稳定状态。课件制作人:XXX7.4线程的优先级在Java语言中,线程有执行的优先级别,优先级的范围是110,默认值为5,可以使用Thread类中setPriority()方法来设定线程的优先级,但必须是在110的范围内,否则会出现异常。优先权较高的线程会被提前执行,当它执行完毕才会轮到优先权较低的线程执行。如

226、果优先权相同,那么采用轮流执行的方式。课件制作人:XXX线程的优先级绝大多数操作系统都支持Timeslicing,简单地说就是操作系统会为每个线程分配一小段CPU时间,时间一到就换下一个线程,即便这个线程没有执行完毕。对于不支持Timeslicing的操作系统,每个线程必须执行完毕后,才轮到下一个线程,如果需要此线程礼让一下其他线程,可以使用Thread类中的yield()方法。课件制作人:XXX7.5线程的控制线程的控制包括线程的启动、挂起、状态检查以及如何正确结束线程,由于在程序中使用多线程,为合理安排线程的执行顺序,可以对线程进行相应的控制。课件制作人:XXX7.5.1线程的启动一个新的

227、线程被创建后处于初始状态,实际上并没有立刻进入运行状态,而是处理就绪状态,当轮到这个线程执行时,即进入“可执行”状态,开始执行线程run()方法中的代码。执行run()方法是通过调用Thread类中start()方法来实现的。调用start()方法启动线程的run()方法不同于一般的调用方法,一般方法必须等到方法执行完毕才能够返回。而对于start()方法来说,调用线程的start()方法后,start()方法告诉系统该线程准备就绪并可以启动run()方法后,就返回,并继续执行调用start()方法下面的语句,这时run()方法可能还在运行,这样,就实现了多任务操作。课件制作人:XXX7.5.

228、2线程的挂起线程的挂起操作实质上就是使线程进入“非可执行”状态下,在这个状态下,CPU不会分给线程时间段,进入这个状态可以用来暂停一个线程的运行,在线程挂起后,可以通过重新唤醒线程来使之恢复运行。这个过程在外表看来好像什么也没有发生过,只是线程很慢地执行一条指令。课件制作人:XXX线程的挂起当一个线程进入“非可执行”状态,也就是挂起状态时,必然存在某种原因使其不能继续运行,这些原因可能是如下几种情况。(1)通过调用sleep()方法使线程进入休眠状态,线程在指定时间内不会运行。(2)通过调用join()方法使线程挂起,如果线程A调用线程B的join()方法,那么线程A将被挂起,直到线程B执行完

229、毕为止。(3)通过调用wait()方法使线程挂起,直到线程得到了notify()和notifyAll()消息,线程才会进入“可执行”状态。(4)线程在等待某个输入/输出完成。课件制作人:XXX线程的挂起sleep()方法sleep()方法是使一个线程的执行暂时停止的方法,暂停的时间由给定的毫秒数决定。语法格式为:millis:必选参数,该参数以毫秒为单位设置线程的休眠时间。执行该方法后,当前线程将休眠指定的时间段,如果任何一个线程中断了当前线程的休眠,该方法将抛出InterruptedException异常对象,所以在使用sleep()方法时,必须捕获该异常。Thread.sleep(long

230、millis)课件制作人:XXX线程的挂起sleep()方法例如:想让线程休眠1.5秒钟,即1500毫秒,可以使用如下代码。tryThread.sleep(1500);/使线程休眠1500毫秒catch(InterruptedExceptione)/捕获异常e.printStackTrace();/输出异常信息课件制作人:XXX线程的挂起join()方法join()方法能够使当前执行的线程停下来等待,直至join()方法所调用的那个线程结束,再恢复执行。语法格式为:thread:一个线程的对象。例如有一个线程A正在运行,用户希望插入一个线程B,并且要求线程B执行完毕,然后再继续线程A,publ

231、icclassAextendsThreadThreadB;run()B.join();/在线程A中执行线程Bthread.join()课件制作人:XXX线程的挂起wait()与notify()方法wait()方法同样可以对线程进行挂起操作,调用wait()方法的线程将进入“非可执行”状态,使用wait()方法有两种方式。语法格式为:或者:thread:线程对象。第一种方式给定线程挂起时间thread.wait(1000);thread.wait();thread.notify();课件制作人:XXX线程的挂起wait()与notify()方法第二种方式是wait()与notify()方法配合使

232、用,这种方式让wait()方法无限等下去,直到线程接收到notify()或则notifyAll()消息为止。wait()、notify()、notifyAll()不同于其他线程方法,这3个方法是java.lang.Object类的一部分,而Object类是所有类的父类,所以这3个方法会自动被所有类继承下来,wait()、notify()、notifyAll()都被声明为final类,所以无法重新定义。课件制作人:XXX线程的挂起suspend()与resume()方法还有一种挂起方法是强制挂起线程,而不是为线程指定休眠时间,这种情况下由其他线程负责唤醒使其继续执行,除了wait()与notif

233、y()方法之外,线程中还有一对方法用于完成此功能,这就是suspend()与resume()方法。语法格式为:thread:线程对象。thread.suspend();thread.resume();课件制作人:XXX线程的挂起suspend()与resume()方法线程thread在运行到suspend()方法之后被强制挂起,暂停运行,直到主线程调用thread.resume()方法时才被重新唤醒。Java的最新版本中已经废弃了suspend()和resume()方法,因为使用这两个方法可能会产生死锁,所以应该使用同步对象调用wait()和notify()方法的机制来代替suspend()和

234、resume()方法进行线程控制。课件制作人:XXX7.5.3线程状态检查一般情况下无法确定一个线程的运行状态,对于这些处于未知状态的线程,可以通过isAlive()方法来确定一个线程是否仍处在活动状态。当然即使处于活动状态的线程也并不意味着这个线程一定正在运行,对于一个已开始运行但还没有完成任务的线程,这个方法返回值为true。isAlive()方法用于测试线程是否处于活动状态。如果线程已经启动且尚未终止,则为活动状态。语法格式为:thread:这是一个线程对象,isAlive()方法将判断该线程的活动状态。thread.isAlive()课件制作人:XXX7.5.4结束线程结束线程有两种情

235、况:(1)自然消亡:一个线程从run()方法的结尾处返回,自然消亡且不能再被运行;(2)强制死亡:调用Thread类中stop()方法强制停止,不过该方法已经被废弃。虽然这两种情况都可以停止一个线程,但最好的方式是自然消亡,简单地说,如果要停止一个线程的执行,最好提供一个方式让线程可以完成run()的流程。例如:线程的run()方法中执行一个无限循环,在这个循环中可以提供一个布尔变量或表达式来控制循环是否执行,在线程执行中,可以调用方法改变布尔变量的值,用这种方式使线程离开run()方法以终止线程。课件制作人:XXXpackagecom;publicclassHelloWorldextends

236、Threadprivatebooleanflag=true;/跳出循环标记量publicbooleanisFlag()/标记量取值returnthis.flag;publicvoidsetFlag(booleanflag)/标记量赋值this.flag=flag;publicvoidrun()while(isFlag()/执行相关业务操作if(!isFlag()/如果标记量为false,结束循环return;课件制作人:XXX7.5.5后台线程后台线程,即Daemon线程,它是一个在后台执行服务的线程。例如操作系统中的隐藏线程和Java语言中的垃圾自动回收线程等。如果所有的非后台线程都结束了,

237、则后台线程也会自动终止。可以使用Thread类中的setDaemon()方法来设置一个线程为后台线程。但是有一点值得注意:必须在线程启动之前调用setDaemon()方法,这样才能将这个线程设置为后台线程。课件制作人:XXX7.5.5后台线程语法格式为:thread:线程对象。on:该参数如果为true,则将该线程标记为后台线程。当设置完成一个后台线程后,可以使用Thread类中的isDaemon()方法来判断线程是否是后台线程。语法格式为:thread:线程对象。thread.setDaemon(booleanon)thread.isDaemon()课件制作人:XXX7.6线程的同步如果程序

238、是单线程的,执行起来不必担心此线程会被其他线程打扰,就像在现实中,同一时间只完成一件事情,可以不用担心这件事情会被其他事情打扰,但是如果程序中同时使用多个线程,就好比现实中“两个人同时进入一扇门”,此时就需要控制,否则容易阻塞。课件制作人:XXX线程的同步为了避免多线程共享资源发生冲突的情况,只要在线程使用资源时给该资源上一把锁就可以了,访问资源的第一个线程为资源上锁,其他线程若想使用这个资源必须等到锁解除为止,锁解开的同时另一个线程使用该资源并为这个资源上锁。课件制作人:XXX线程的同步例如将银行中的某个窗口看作是一个公共资源的话,每个客户需要办理的业务就相当于一个线程,而排号系统就相当于给

239、每个窗口上了锁,保证每个窗口只有一个客户在办理业务。当其中一个客户办理完业务后,工作人员启动排号机,通知下一个客户来办理业务,这正是线程A将锁打开,通知第二个线程来使用资源的过程。课件制作人:XXX线程的同步为了处理这种共享资源竞争,可以使用同步机制。所谓同步机制指的是两个线程同时操作一个对象时,应该保持对象数据的统一性和整体性。Java语言提供synchronized关键字,为防止资源冲突提供了内置支持。共享资源一般是文件、输入/输出端口,或者是打印机。Java语言中有两种同步形式,即同步方法和同步代码块。课件制作人:XXX线程的同步(同步方法)同步方法将访问这个资源的方法都标记为synch

240、ronized,这样在需要调用这个方法的线程执行完之前,其他调用该方法的线程都会被阻塞。可以使用如下代码声明一个synchronized方法:【例7-3】synchronizedvoidsum()./定义取和的同步方法synchronizedvoidmax()./定义取最大值的同步方法课件制作人:XXX线程的同步(同步代码块)Java语言中同步的设定不只应用于同步方法,也可以设置程序的某个代码段块为同步区域。语法格式为:其中somobject代表当前对象,同步的作用区域是synchronized关键字后大括号以内的部分。在程序执行到synchronized设定的同步化区块时锁定当前对象,这样就

241、没有其他线程可以执行这个被同步化的区块。【例7-4】synchronized(someobject)/省略代码课件制作人:XXX7.7线程通信在程序开发中,经常创建多个不相同的线程来完成不相关的任务,然而,有时执行的任务可能有一定联系,这样就需要使这些线程进行交互。比如有一个水塘,对水塘操作无非包括“进水”和“排水”,这两个行为各自代表一个线程,当水塘中没有水时,“排水”行为不能再进行,当水塘水满时,“进水”行为不能再进行。课件制作人:XXX线程通信在Java语言中用于线程间通信的方法是前文中提到过的wait()与notify()方法,拿水塘的例子来说明,线程A代表“进水”,线程B代表“排水”

242、,这两个线程对水塘都具有访问权限。假设线程B试图做“排水”行为,然而水塘中却没有水。这时候线程B只好等待一会。线程B可以使用如下代码:if(water.isEmpty)/如果水塘没有水water.wait();/线程等待课件制作人:XXX线程通信在由线程A往水塘注水之前,线程B不能从这个队列中释放,它不能再次运行。当线程A将水注入水塘中后,应该由线程A来通知线程B水塘中已经被注入水了,线程B才可以运行。此时,水塘对象将等待队列中第一个被阻塞的线程在队列中释放出来,并且重新加入程序运行。水塘对象可以使用如下代码:water.notify();课件制作人:XXX线程通信将“进水”与“排水”抽象为线

243、程A和线程B。“水塘”抽象为线程A与线程B共享对象water,上述情况即可看作线程通信,线程通信可以使用wait()与notify()方法。notify()方法最多只能释放等待队列中的第一个线程,如果有多个线程在等待,可以使用notifyAll()方法,释放所有线程。另外,wait()方法除了可以被notify()调用终止以外,还可以通过调用线程的interrupt()方法来中断,通过调用线程的interrupt()方法来终止,wait()方法会抛出一个异常。因此,如同sleep()方法,也需要将wait()方法放在trycatch语句块中。课件制作人:XXX线程通信将“进水”与“排水”抽象为

244、线程A和线程B。“水塘”抽象为线程A与线程B共享对象water,上述情况即可看作线程通信,线程通信可以使用wait()与notify()方法。notify()方法最多只能释放等待队列中的第一个线程,如果有多个线程在等待,可以使用notifyAll()方法,释放所有线程。另外,wait()方法除了可以被notify()调用终止以外,还可以通过调用线程的interrupt()方法来中断,通过调用线程的interrupt()方法来终止,wait()方法会抛出一个异常。因此,如同sleep()方法,也需要将wait()方法放在trycatch语句块中。课件制作人:XXX线程通信在实际应用中,wait(

245、)与notify()方法必须在同步方法或同步块中调用,因为只有获得这个共享对象,才可能释放它。为了使线程对一个对象调用wait()或notify()方法,线程必须锁定那个特定的对象,这个时候就需要同步机制进行保护。课件制作人:XXX线程通信例如,当“排水”线程得到对水塘的控制权时,也就是拥有了water这个对象,但水塘中却没有水,此时,water.isEmpty()条件满足,water对象被释放,所以“排水”线程在等待。可以使用如下代码在同步机制保护下调用wait()方法:synchronized(water)/省略部分代码tryif(water.isEmpty()water.wait();/

246、线程调用wait()方法catch(InterruptExceptione)/省略异常处理代码课件制作人:XXX线程通信当“进水”线程将水注入水塘后,再通知等待的“排水”线程,告诉它可以排水了,“排水”线程被唤醒后继续做排水工作。notify()方法通知“排水”线程,并将其唤醒,notify()方法与wait()方法相同,都需要在同步方法或同步块中才能被调用。下面是在同步机制下调用notify()方法的代码:【例7-5】synchronized(water)water.notify();/线程调用notify()方法课件制作人:XXX7.8多线程产生死锁因为线程可以阻塞,并且具有同步控制机制可

247、以防止其他线程在锁还没有释放的情况下访问这个对象,这时就产生了矛盾,比如:线程A在等待线程B,而线程B又在等待线程A,这样就造成了死锁。一般造成死锁必须同时满足如下4个条件:n互斥条件:线程使用的资源必须至少有一个是不能共享的;n请求与保持条件:至少有一个线程必须持有一个资源并且正在等待获取一个当前被其他线程持有的资源;n非剥夺条件:分配的资源不能从相应的线程中被强制剥夺;n循环等待条件:第一个线程等待其他线程,后者又在等待第一个线程序。因为要发生死锁,这4个条件必须同时满足,所以要防止死锁的话,只需要破坏其中一个条件即可。课件制作人:XXX7.9异常异常是指程序在运行时产生的错误。比如在进行

248、除法运算时,若除数为0,则运行时Java会自动抛出算术异常、若对一个值为null的引用变量进行操作,则会抛出空指针异常、若访问一个大小为2的一维数组中的第3个元素,则会抛出数组下标越界异常等。Java语言中的异常也是通过一个对象来表示的,程序运行时抛出的异常,实际上就是一个异常对象。该对象中不仅封装了错误信息,还提供了一些处理方法,如getMessage()方法获取异常信息、printStackTrace()方法输出对异常的详细描述信息等。课件制作人:XXX异常对于可能出现的异常,都需要预先进行处理,保证程序的有效运行,否则程序会出错。在Java语言中已经提供了一些异常用来描述经常发生的错误,

249、对于这些异常,有的需要程序员进行捕获处理或声明抛出,称为“受检查异常”;有的是由Java虚拟机自动进行捕获处理,称为“运行时异常”或“不受检异常”。Java中常见的异常如下表所示:课件制作人:XXX异常类名称异常类含义ArithmeticException算术异常类ArrayIndexOutOfBoundsException数组下标越界异常类ArrayStoreException将与数组类型不兼容的值赋值给数组元素时抛出的异常ClassCastException类型强制转换异常类ClassNotFoundException为找到相应类异常EOFException文件已结束异常类FileNotF

250、oundException文件未找到异常类IllegalAccessException访问某类被拒绝时抛出的异常InstantiationException试图通过newInstance()方法创建一个抽象类或抽象接口的实例时抛出的异常IOException输入输出异常类NegativeArraySizeException建立元素个数为负数的数组异常类NullPointerException空指针异常类NumberFormatException字符串转换为数字异常类NoSuchFieldException字段未找到异常类NoSuchMethodException方法未找到异常类Security

251、Exception小应用程序(Applet)执行浏览器的安全设置禁止的动作时抛出的异常SQLException操作数据库异常类StringIndexOutOfBoundsException字符串索引超出范围异常课件制作人:XXX7.9.1异常处理异常产生后,若不做任何处理,则程序就会被终止,为了保证程序有效的执行,就需要对产生的异常进行相应处理。在Java语言中,若某个方法抛出异常,既可以在当前方法中进行捕获,然后处理该异常,也可以将异常向上抛出,由方法的调用者来处理。下面来介绍Java中的异常处理方法。课件制作人:XXX异常处理使用trycatch语句在Java语言中,对容易发生异常的代码,

252、可通过trycatch语句捕获。在try语句块中编写可能发生异常的代码,然后在catch语句块中捕获执行这些代码时可能发生的异常。一般格式格式为:try可能产生异常的代码catch(异常类异常对象)异常处理代码课件制作人:XXX异常处理使用trycatch语句try语句块中的代码可能同时存在多种异常,那么到底捕获的是哪一种类型的异常,是由catch语句中的“异常类”参数来指定的。catch语句类似于方法的声明,包括一个异常类型和该类的一个对象,异常类必须是Throwable类的子类,用来指定了catch语句要捕获的异常,异常类对象可在catch语句块中被调用,例如调用对象的getMessage

253、()方法获取对异常的描述信息。课件制作人:XXX异常处理使用trycatch语句将一个字符串转换为整型,可通过Integer类的parseInt()方法来实现。当该方法的字符串参数包含非数字字符时,parseInt()方法会抛出异常。Integer类的parseInt()方法的声明如下:代码中通过throws语句抛出了NumberFormatException异常,所以在应用parseInt()方法时可通过trycatch语句来捕获该异常,从而进行相应的异常处理。publicstaticintparseInt(Strings)throwsNumberFormatException课件制作人:X

254、XX异常处理使用trycatch语句例如将字符串“24L”转换为Integer类型,并捕获转换中产生的数字格式异常,可以使用如下代码:tryintage=Integer.parseInt(24L);/抛出NumberFormatException异常System.out.println(打印1);catch(NumberFormatExceptione)/捕获NumberFormatException异常System.out.println(年龄请输入整数!);System.out.println(错误:+e.getMessage();System.out.println(打印2);课件制作人

255、:XXX异常处理使用trycatch语句因为程序执行到“Integer.parseInt(24L)”时抛出异常,直接被catch语句捕获,程序流程跳转到catch语句块内继续执行,所以“System.out.println(打印1)”代码行不会被执行;而异常处理结束后,会继续执行trycatch语句后面的代码。说明:若不知代码抛出的是哪种异常,可指定它们的父类Exception。课件制作人:XXX异常处理使用trycatch语句在trycatch语句中,可以同时存在多个catch语句块。一般格式为:代码中的每个catch语句块都用来捕获一种类型的异常。若try语句块中的代码发生异常,则会由上而

256、下依次来查找能够捕获该异常的catch语句块,并执行该catch语句块中的代码。try可能产生异常的代码catch(异常类1异常对象)异常1处理代码catch(异常类2异常对象)异常2处理代码课件制作人:XXX异常处理使用trycatch语句在使用多个catch语句捕获try语句块中的代码抛出的异常时,需要注意catch语句的顺序。若多个catch语句所要捕获的异常类之间具有继承关系,则用来捕获子类的catch语句要放在捕获父类的catch语句的前面。否则,异常抛出后,先由捕获父类异常的catch语句捕获,而捕获子类异常的catch语句将成为执行不到的代码,在编译时会出错。例如:tryinta

257、ge=Integer.parseInt(24L);/抛出NumberFormatException异常catch(Exceptione)/先捕获Exception异常System.out.println(e.getMessage();catch(NumberFormatExceptione)/捕获异常类Exception的子类异常System.out.println(e.getMessage();课件制作人:XXX异常处理使用trycatch语句代码中第二个catch语句捕获的NumberFormatException异常是Exception异常类的子类,所以try语句块中的代码抛出异常后,先

258、由第一个catch语句块捕获,其后的catch语句块成为执行不到的代码,编译时发生如下异常:执行不到的NumberFormatException的catch块。它已由Exception的catch块处理课件制作人:XXX异常处理finally子句的用法finally子句需要与trycatch语句一同使用,不管程序中有无异常发生,并且不管之前的trycatch是否顺利执行完毕,最终都会执行finally语句块中的代码,这使得一些不管在任何情况下都必须执行的步骤被执行,从而保证了程序的健壮性。【例7-6】课件制作人:XXX异常处理使用throws关键字抛出异常若某个方法可能会发生异常,但不想在当前

259、方法中来处理这个异常,那么可以将该异常抛出,然后在调用该方法的代码中捕获该异常并进行处理。将异常抛出,可通过throws关键字来实现。throws关键字通常被应用在声明方法时,用来指定方法可能抛出的异常,多个异常可用逗号分隔。【例7-7】课件制作人:XXX异常处理使用throw关键字使用throw关键字也可抛出异常,与throws不同的是,throw用于方法体内,并且抛出一个异常类对象,而throws用在方法声明中来指明方法可能抛出的多个异常。通过throw抛出异常后,如果想由上一级代码来捕获并处理异常,则同样需要在抛异常的方法中使用throws关键字在方法的声明中指明要抛出的异常;如果想在当

260、前的方法中捕获并处理throw抛出的异常,则必须使用trycatch语句。上述两种情况,若throw抛出的异常是Error、RuntimeException或它们的子类,则无须使用throws关键字或trycatch语句。课件制作人:XXX异常处理使用throw关键字当输入的年龄为负数时,Java虚拟机当然不会认为这是一个错误,但实际上年龄是不能为负数的,可通过异常的方式来处理这种情况。【例7-8】课件制作人:XXX7.9.2异常类在Java语言中提供了一些内置的异常类来描述经常较容易发生的错误,这些类都继承自java.lang.Throwable类。Throwable类有两个子类:Error

261、和Exception,它们分别表示两种异常类型。课件制作人:XXX7.9.3Error类Error类及其子类通常用来描述Java运行系统中的内部错误以及资源耗尽的错误。Error表示的异常是比较严重,仅靠修改程序本身是不能恢复执行的,被称为致命异常类。举一个现实中的例子,例如,因施工时偷工减料,导致学校教学楼坍塌,此时就相当于发生了一个Error异常。在大多数情况下,发生该异常时,建议终止程序。课件制作人:XXX7.9.4Exception类Exception类可称为非致命异常类,它代表了另一种异常。发生该异常的程序,通过捕获处理后可正常运行,保持程序的可读性及可靠性。在开发Java程序过程中

262、进行的异常处理,主要就是针对该类及其子类的异常处理。对程序中可能发生的该类异常,应该尽可能进行处理,以保证程序在运行时,能够顺利执行,而不应该在异常发生后终止程序。Exception类又分为两种异常类型:nRuntimeException异常n检查异常。课件制作人:XXXRuntimeException异常RuntimeException是运行时异常,也称为不检查异常(uncheckedexception),是程序员编写的程序中的错误导致的,修改了该错误后,程序就可继续执行。例如,学校制定校规,若有学生违反了校规,就相当发生了一个RuntimeException异常。在程序中发生该异常的情况如

263、除数为0的运算、数组下标越界、对没有初始化的对象进行操作等。当RuntimeExeption类或其子类所描述的异常发生后,可以不通过trycatch、throws捕获或抛出,在编译时是可以通过的,只是在运行时由Java虚拟机来抛出。常见的RuntimeException异常如下表所示:课件制作人:XXX异常类名称异常类含义ArithmeticException算术异常类ArrayIndexOutOfBoundsException数组下标越界异常类ArrayStoreException将与数组类型不兼容的值赋值给数组元素时抛出的异常ClassCastException类型强制转换异常类Index

264、OutOfBoundsException当某对象(如数组或字符串)的索引超出范围时抛出该异常NegativeArraySizeException建立元素个数为负数的数组异常类NullPointerException空指针异常类NumberFormatException字符串转换为数字异常类SecurityException小应用程序(Applet)执行浏览器的安全设置禁止的动作时抛出的异常StringIndexOutOfBoundsException字符串索引超出范围异常课件制作人:XXX检查异常如果一个记者根据上级指定的地址去采访一个重要人物,这可能会抛出异常,例如根据指定地址没有找到被采访

265、的人或采访被拒绝。该类异常被称为检查异常(checkexception),要求必须通过trycatch捕获或由throws抛出,否则编译出错。Java语言中常见的检查异常如下表所示课件制作人:XXX异常类名称异常类含义ClassNotFoundException未找到相应类异常EOFException文件已结束异常类FileNotFoundException文件未找到异常类IllegalAccessException访问某类被拒绝时抛出的异常InstantiationException试图通过newInstance()方法创建一个抽象类或抽象接口的实例时抛出该异常IOException输入输出

266、异常类NoSuchFieldException字段未找到异常NoSuchMethodException方法未找到异常SQLException操作数据库异常类课件制作人:XXX7.9.5自定义异常通常使用Java内置的异常类就可以描述在编写程序时出现的大部分异常情况,但根据需要,有时要创建自己的异常类,并将它们用于程序中来描述Java内置异常类所不能描述的一些特殊情况。下面就来介绍如何创建和使用自定义异常。自定义的异常类必须继承自Throwable类,才能被视为异常类,通常是继承Throwable的子类Exception或Exception类的子孙类。除此之外,与创建一个普通类的语法相同。课件制

267、作人:XXX自定义异常自定义异常类大体可分为以下几个步骤。(1)创建自定义异常类。(2)在方法中通过throw抛出异常对象。(3)若在当前抛出异常的方法中处理异常,可使用trycatch语句捕获并处理;否则在方法的声明处通过throws指明要抛出给方法调用者的异常,继续进行下一步操作。(4)在出现异常的方法调用代码中捕获并处理异常。如果自定义的异常类继承自RuntimeExeption异常类,在步骤(3)中,可以不通过throws指明要抛出的异常。下面通过一个实例来讲解自定义异常类的创建及使用。【例7-9】JSP程序设计教程课件 制作人:XXXJava实用教程第8章Swing程序设计课件制作人

268、:XXX第8章Swing程序设计8.1Swing概述8.2创建窗体8.3常用组件8.4常用布局管理器8.5常用面板8.6常用事件处理8.7拼图游戏课件制作人:XXX8.2创建窗体在开发Java应用程序时,通常情况下利用JFrame类创建窗体。利用JFrame类创建的窗体分别包含标题、最小化按钮、最大化按钮和关闭按钮。JFrame类提供了一系列用来设置窗体的方法,例如通过的setTitle(Stringtitle)方法,可以设置窗体的标题;通过setBounds(intx,inty,intwidth,intheight)方法可以设置窗体的显示位置及大小,该方法接受4个int型参数,前两个参数用来

269、设置窗体的显示位置,依次为窗体左上角的点在显示器中的水平和垂直坐标,后两个参数用来设置窗体的大小,依次为窗体的宽度和高度。课件制作人:XXX创建窗体在创建窗体时,通常情况下需要设置关闭按钮的动作。关闭按钮的默认动作为将窗体隐藏,可以通过方法setDefaultCloseOperation(intoperation)设置关闭按钮的动作,该方法的入口参数可以从JFrame类提供的静态常量中选择,可选的静态常量如下表所示。【例8-1】静 态 常 量常 量 值执 行 操 作HIDE_ON_CLOSE1隐藏窗口,为默认操作DO_NOTHING_ON_CLOSE0不执行任何操作DISPOSE_ON_CLO

270、SE2移除窗口EXIT_ON_CLOSE3退出窗口课件制作人:XXX8.3常用组件软件界面是软件和用户之间的交流平台,而组件则是绘制软件界面的基本元素,是软件和用户之间的交流要素。例如用文本框来显示相关信息,用单选按钮、复选按钮、文本框等接受用户的输入信息,用按钮来提交用户的输入信息。本节将对用来绘制软件界面的常用组件做详细的介绍,并针对每个组件给出一个典型例子,以方便读者学习和参考。课件制作人:XXX8.3.1JLabel(标签)组件JLabel组件用来显示文本和图像,可以只显示其中的一者,也可以二者同时显示。JLabel类提供了一系列用来设置标签的方法,例如通过setText(String

271、text)方法设置标签显示的文本,通过setFont(Fontfont)方法设置标签文本的字体及大小,通过setHorizontalAlignment(intalignment)方法设置文本的显示位置,该方法的参数可以从JLabel类提供的静态常量中选择,可选的静态常量如下表所示。静 态 常 量常 量 值标签内容显示位置LEFT2靠左侧显示CENTER0居中显示RIGHT4靠右侧显示课件制作人:XXXJLabel(标签)组件如果需要在标签中显示图片,可以通过setIcon(Iconicon)方法设置。如果想在标签中既显示文本,又显示图片,可以通过setHorizontalTextPositio

272、n(inttextPosition)方法设置文字相对图片在水平方向的显示位置。还可以通过setVerticalTextPosition(inttextPosition)方法设置文字相对图片在垂直方向的显示位置,该方法的入口参数可以从JLabel类提供的静态常量中选择,可选的静态常量如下表所示。【例8-2】静 态 常 量常 量 值标签内容显示位置TOP1文字显示在图片的上方CENTER0文字与图片在垂直方向重叠显示BOTTOM3文字显示在图片的下方课件制作人:XXXJButton(按钮)组件JButton组件是最简单的按钮组件,只是在按下和释放两个状态之间进行切换,可以通过捕获按下并释放的动作执

273、行一些操作,从而完成和用户的交互。JButton类提供了一系列用来设置按钮的方法,例如通过setText(Stringtext)方法设置按钮的标签文本,通过下面的代码就可以创建一个最简单按钮:finalJButtonbutton=newJButton();button.setBounds(10,10,70,23);button.setText(确定);getContentPane().add(button);课件制作人:XXXJButton(按钮)组件更多的是为按钮设置图片,方法setIcon(IcondefaultIcon)用来设置按钮在默认状态下显示的图片;方法setRolloverIco

274、n(IconrolloverIcon)用来设置当光标移动到按钮上方时显示的图片;方法setPressedIcon(IconpressedIcon)用来设置当按钮被按下时显示的图片。课件制作人:XXXJButton(按钮)组件当将按钮设置为显示图片时,建议通过setMargin(Insetsm)方法将按钮边框和标签四周的间隔均设置为0,该方法的入口参数为Insets类的实例,Insets类的构造方法为Insets(inttop,intleft,intbottom,intright),该方法接受4个int型参数,依次为标签上方、左测、下方和右侧的间隔;通过setContentAreaFilled(

275、booleanb)方法设置为不绘制按钮的内容区域,也可以理解为设置按钮的背景为透明,当设为false时表示不绘制,默认为绘制;通过setBorderPainted(booleanb)方法设置为不绘制按钮的边框,当设为false时表示不绘制,默认为绘制。【例8-3】课件制作人:XXX8.3.3JRadioButton(单选按钮)组件JRadioButton组件实现一个单选按钮,用户可以很方便地查看单选按钮的状态。JRadioButton类可以单独使用,也可以与ButtonGroup类联合使用,当单独使用时,该单选按钮可以被选定和取消选定,当与ButtonGroup类联合使用时,则组成了一个单选按

276、钮组,此时用户只能选定按钮组中的一个单选按钮,取消选定的操作将由ButtonGroup类自动完成。ButtonGroup类用来创建一个按钮组,按钮组的作用是负责维护该组按钮的“开启”状态,在按钮组中只能有一个按钮处于“开启”状态。假设在按钮组中有且仅有A按钮处于开启状态,在“开启”其他按钮时,按钮组将自动关闭A按钮的“开启”状态。课件制作人:XXXJRadioButton(单选按钮)组件按钮组经常用来维护由JRadioButton、JRadioButtonMenuItem或JToggleButton类型的按钮组成的按钮组。ButtonGroup类提供的常用方法如下表所示:方 法功 能add(A

277、bstractButton b)添加按钮到按钮组中remove(AbstractButton b)从按钮组中移除按钮getButtonCount()返回按钮组中包含按钮的个数,返回值为int型getElements()返回一个Enumeration类型的对象,通过该对象可以遍历按钮组中包含的所有按钮对象课件制作人:XXXJRadioButton(单选按钮)组件JRadioButton类提供了一系列用来设置单选按钮的方法,例如通过setText(Stringtext)方法设置单选按钮的标签文本,通过setSelected(booleanb)方法设置单选按钮的状态,默认情况下未被选中,当设为tru

278、e时表示单选按钮被选中。【例8-4】课件制作人:XXX8.3.4JCheckBox(复选框)组件JCheckBox组件实现一个复选框,该复选框可以被选定和取消选定,并且可以同时选定多个。用户可以很方便地查看复选框的状态。JCheckBox类提供了一系列用来设置复选框的方法,例如通过setText(Stringtext)方法设置复选框的标签文本,通过setSelected(booleanb)方法设置复选框的状态,默认情况下未被选中,当设为true时表示复选框被选中。【例8-5】课件制作人:XXX8.3.5JComboBox(选择框)组件JComboBox组件实现一个选择框,用户可以从下拉列表中选

279、择相应的值,该选择框还可以设置为可编辑的,当设置为可编辑状态时,用户可以在选择框中输入相应的值。在创建选择框时,可以通过构造函数JComboBox(Objectitems)直接初始化该选择框包含的选项。课件制作人:XXXJComboBox(选择框)组件例如创建一个包含选项“身份证”、“士兵证”和“驾驶证”的选择框,具体代码如下:也可以通过setModel(ComboBoxModelaModel)方法初始化该选择框包含的选项,例如:还可以通过方法addItem(Objectitem)和insertItemAt(Objectitem,intindex)向选择框中添加选项,例如:StringidCa

280、rds=身份证,士兵证,驾驶证;JComboBoxidCardComboBox=newJComboBox(idCards);StringidCards=身份证,士兵证,驾驶证;JComboBoxidCardComboBox=newJComboBox();comboBox.setModel(newDefaultComboBoxModel(idCards);JComboBoxidCardComboBox=newJComboBox();comboBox.addItem(士兵证);comboBox.addItem(驾驶证);comboBox.insertItemAt(身份证,0);课件制作人:XXXJ

281、ComboBox(选择框)组件JComboBox类提供了一系列用来设置选择框的方法,例如通过方法setSelectedItem()或setSelectedIndex()设置选择框的默认选项;通过方法setEditable()设置选择框是否可编辑。JComboBox类提供的常用方法如下表所示。【例8-6】方 法功 能addItem(Object item)添加选项到选项列表的尾部insertItemAt(Object item, int index)添加选项到选项列表的指定索引位置,索引从0开始removeItem(Object item)从选项列表中移除指定的选项removeItemAt(in

282、t index)从选项列表中移除指定索引位置的选项removeAllItems()移除选项列表中的所有选项setSelectedItem(Object item)设置指定选项为选择框的默认选项setSelectedIndex(int index)设置指定索引位置的选项为选择框的默认选项setMaximumRowCount(int count)设置选择框弹出时显示选项的最多行数,默认为8行setEditable(boolean isEdit)设置选择框是否可编辑,当设置为true时表示可编辑,默认为不可编辑(false)课件制作人:XXX8.3.6JList(列表框)组件JList组件实现一个列

283、表框,列表框与选择框的主要区别是列表框可以多选,而选择框只能单选。在创建列表框时,需要通过构造函数JList(Objectlist)直接初始化该列表框包含的选项,例如创建一个用来选择月份的选择框,具体代码如下:Integermonths=1,2,3,4,5,6,7,8,9,10,11,12;JListlist=newJList(months);课件制作人:XXXJList(列表框)组件由JList组件实现的列表框有三种选取模式,可以通过JList类的setSelectionMode(intselectionMode)方法设置具体的选取模式,该方法的参数可以从ListSelectionModel

284、类中的静态常量中选择。这三种选取模式包括一种单选模式和两种多选模式,具体信息如下表所示。静 态 常 量常 量 值标签内容显示位置SINGLE_SELECTION0只允许选取一个SINGLE_INTERVAL_SELECTION1只允许连续选取多个MULTIPLE_INTERVAL_SELECTION2既允许连续选取,又允许间隔选取课件制作人:XXXJList类提供了一系列用来设置列表框的方法,常用方法如下表所示。【例8-7】方 法功 能setSelectedIndex(int index)选中指定索引的一个选项setSelectedIndices(int indices)选中指定索引的一组选项

285、setSelectionBackground(Color selectionBackground)设置被选项的背景颜色setSelectionForeground(Color selectionForeground)设置被选项的字体颜色getSelectedIndices()以int形式获得被选中的所有选项的索引值getSelectedValues()以Object形式获得被选中的所有选项的内容clearSelection()取消所有被选中的项isSelectionEmpty()查看是否有被选中的项,如果有则返回trueisSelectedIndex(int index)查看指定项是否已经被选

286、中ensureIndexIsVisible(int index)使指定项在选择窗口中可见setFixedCellHeight(int height)设置选择窗口中每个选项的高度setVisibleRowCount(int visibleRowCount)设置在选择窗口中最多可见选项的个数getPreferredScrollableViewportSize()获得使指定个数的选项可见需要的窗口高度setSelectionMode(int selectionMode)设置列表框的选择模式,即单选还是多选课件制作人:XXX8.3.7JTextField(文本框)组件JTextField组件实现一个文

287、本框,用来接受用户输入的单行文本信息。如果需要为文本框设置默认文本,可以通过构造函数JTextField(Stringtext)创建文本框对象,例如:也可以通过方法setText(Stringt)为文本框设置文本信息,例如:JTextFieldtextField=newJTextField(请输入姓名);textField.setText(请输入姓名);JTextFieldtextField=newJTextField(请输入姓名);课件制作人:XXXJTextField(文本框)组件在设置文本框时,可以通过setHorizontalAlignment(intalignment)方法设置文本框

288、内容的水平对齐方式,该方法的入口参数可以从JTextField类中的静态常量中选择,具体信息如下表所示。静 态 常 量常 量 值标签内容显示位置LEFT2靠左侧显示CENTER0居中显示RIGHT4靠右侧显示课件制作人:XXXJTextField(文本框)组件JTextField类提供的常用方法如下表所示。【例8-8】方 法功 能getPreferredSize()获得文本框的首选大小,返回值为Dimensions类型的对象scrollRectToVisible(Rectangle r)向左或向右滚动文本框中的内容setColumns(int columns)设置文本框最多可显示内容的列数se

289、tFont(Font f)设置文本框的字体setScrollOffset(int scrollOffset)设置文本框的滚动偏移量(以像素为单位)setHorizontalAlignment(int alignment)设置文本框内容的水平对齐方式课件制作人:XXX8.3.8JPasswordField(密码框)组件JPasswordField组件实现一个密码框,用来接受用户输入的单行文本信息,在密码框中并不显示用户输入的真实信息,而是通过显示一个指定的回显字符作为占位符。新创建密码框的默认回显字符为“*”,可以通过setEchoChar(charc)方法修改回显字符,例如将回显字符修改为“#

290、”。这两中效果如下图所示:课件制作人:XXXJPasswordField(密码框)组件JPasswordField类提供的常用方法如下表所示。【例8-9】方 法功 能setEchoChar(char c)设置回显字符为指定字符getEchoChar()获得回显字符,返回值为char型echoCharIsSet()查看是否已经设置了回显字符,如果设置了则返回true,否则返回falsegetPassword()获得用户输入的文本信息,返回值为char型数组课件制作人:XXX8.3.9JTextArea(文本域)组件JTextArea组件实现一个文本域,文本域可以接受用户输入的多行文本。在创建文本

291、域时,可以通过setLineWrap(booleanwrap)方法设置文本是否自动换行,默认为false,即不自动换行,如果改为自动换行,需要设置wrap参数为true。JTextArea类的常用方法如下表所示【例8-10】方 法功 能append(String str)将指定文本追加到文档结尾insert(String str, int pos)将指定文本插入指定位置replaceRange(String str, int start, int end)用指定新文本替换从指示的起始位置到结尾位置的文本getColumnWidth()获取列的宽度getColumns()返回文本域中的列数get

292、LineCount()确定文本区中所包含的行数getPreferredSize()返回文本域的首选大小getRows()返回文本域中的行数setLineWrap(boolean wrap)设置文本区是否自动换行,默认为false,即不自动换行课件制作人:XXX8.4常用布局管理器布局管理器负责管理组件在容器中的排列方式。Java是跨平台的开发语言,它能够实现“一次编写,到处运行”,为实现这个目标,Java所开发的应用程序,必须使用布局管理器管理每个容器中组件的布局,因为不同的平台(即操作系统或者手机等硬件平台)显示组件的策略和方式是不同的,无法确定不同平台的组件大小和样式。虽然Java提供了空

293、布局管理器的支持(即不使用布局管理器),但那是在牺牲跨平台性能的前提下,才使用的布局管理方式。本节将介绍程序开发中常用的几种布局管理器。课件制作人:XXX8.4.1不使用布局管理器在布局管理器出现之前,所有的应用程序都使用直接定位的方式排列容器中的组件,例如VC、Delphi、VB等开发语言都使用这种布局方式。Java也提供了对绝对定位的组件排列方式的支持,但是这样布局的程序界面不能保证在其他操作平台中也能正常显示。如果需要开发的程序只在单一的系统中使用,可以考虑使用这种布局管理方式。通过setLayout(LayoutManagermgr)方法设置组件容器采用的布局管理器,如果不采用任何布局

294、管理器,则可以将其设置为null,例如:【例8-11】getContentPane().setLayout(null);课件制作人:XXX8.4.2FlowLayout布局管理器由FlowLayout类实现的布局管理器称为流布局管理器,它的布局方式是首先在一行上排列组件,当该行没有足够的空间时,则回行显示,当容器的大小发生改变时,将自动调整组件的排列方式。如下图所示:课件制作人:XXXFlowLayout布局管理器流布局管理器默认为居中显示组件,可以通过FlowLayout类的setAlignment(intalign)方法设置组件的对齐方式,该方法的参数可以从FlowLayout类的静态常量

295、中选择,如下表所示。流布局管理器默认组件的水平间距和垂直间距均为5像素,可以通过FlowLayout类的方法setHgap(inthgap)和setVgap(intvgap)设置组件的水平间距和垂直间距。【例8-12】静 态 常 量常 量 值组件对齐方式LEFT0靠左侧显示CENTER1居中显示,为默认对齐方式RIGHT2靠右侧显示课件制作人:XXX8.4.3BorderLayout布局管理器由BorderLayout类实现的布局管理器称为边界布局管理器,它的布局方式是将容器划分为5个部分。边界布局管理器为JFrame窗体的默认布局管理器,其布局格式如下图所示。课件制作人:XXXBorderL

296、ayout布局管理器如果组件容器采用了边界布局管理器,将组件添加到容器时,需要设置组件的显示位置,通过方法add(Componentcomp,Objectconstraints)添加并设置,该方法的第一个参数为欲添加的组件对象,第二个参数为组件的显示位置,可以从BorderLayout类的静态常量中选择,如下表所示。边界布局管理器默认组件水平间距和垂直间距均为0像素,可以通过BorderLayout类的方法setHgap(inthgap)和setVgap(intvgap)设置组件的水平间距和垂直间距。【例8-13】静 态 常 量常 量 值组件对齐方式CENTERCenter显示在容器中间NOR

297、THNorth显示在容器顶部SOUTHSouth显示在容器底部WESTWest显示在容器左侧EASTEast显示在容器右侧课件制作人:XXX8.4.4GridLayout布局管理器由GridLayout类实现的布局管理器称为网格布局管理器,它的布局方式是将容器按照用户的设置平均划分成若干网,如下图所示。在通过构造方法GridLayout(introws,intcols)创建网格布局管理器对象时,参数rows用来设置网格的行数,参数cols用来设置网格的列数,在设置时分为以下4种情况:课件制作人:XXXGridLayout布局管理器(1)只设置了网格的行数,即rows大于0,cols等于0:在这

298、种情况下,容器将先按行排列组件,当组件个数大于rows时,则再增加一列,依次类推;(2)只设置了网格的列数,即rows等于0,cols大于0:在这种情况下,容器将先按列排列组件,当组件个数大于cols时,则再增加一行,依次类推;(3)同时设置了网格的行数和列数,即rows大于0,cols大于0:在这种情况下,容器将先按行排列组件,当组件个数大于rows时,则再增加一列,依次类推;课件制作人:XXXGridLayout布局管理器(4)同时设置了网格的行数和列数,但是容器中的组件个数大于网格数(rowscols);在这种情况下,将再增加一列,依次类推。网格布局管理器默认组件的水平间距和垂直间距均为

299、0像素,可以通过GridLayout类的方法setHgap(inthgap)和setVgap(intvgap)设置组件的水平间距和垂直间距。【例8-14】课件制作人:XXX8.5常用面板可以将面板添加到JFrame窗体中,也可以将子面板添加到上级面板中,然后将组件添加到面板中。通过使用面板,可以实现对所有组件进行分层管理,即对不同关系的组件采用不同的布局管理方式,使组件的布局更合理,使软件界面更美观。课件制作人:XXX8.5.1JPanel面板如果将所有的组件都添加到由JFrame窗体提供的默认组件容器中,将存在如下两个问题:(1)一个界面中的所有组件只能采用一种布局方式,这样很难得到一个美观

300、的界面;(2)有些布局方式只能管理有限个组件,例如JFrame窗体默认的BorderLayout布局管理器,最多只能管理5个组件。课件制作人:XXXJPanel面板针对上面这两个问题,通过使用JPanel面板就可以解决,首先将面板和组件添加到JFrame窗体中,然后再将子面板和组件添加到上级面板中,这样就可以向面板中添加无数个组件,并且通过对每个面板采用不同的布局管理器,真正解决众多组件间的布局问题。JPanel面板默认采用FlowLayout布局管理器。【例8-15】课件制作人:XXX8.5.1JScrollPane面板JScrollPane类实现了一个带有滚动条的面板,用来为某些组件添加滚

301、动条,例如在学习JList和JTextArea组件时均用到了该组件,JScrollPane类提供的常用方法如下表所示。方 法功 能setViewportView(Component view)设置在滚动面板中显示的组件对象setHorizontalScrollBarPolicy(int policy)设置水平滚动条的显示策略setVerticalScrollBarPolicy(int policy)设置垂直滚动条的显示策略setWheelScrollingEnabled(false)设置滚动面板的滚动条是否支持鼠标的滚动轮课件制作人:XXXJScrollPane面板JScrollPane类实现

302、了一个带有滚动条的面板,用来为某些组件添加滚动条,例如在学习JList和JTextArea组件时均用到了该组件,JScrollPane类提供的常用方法如下表所示。方 法功 能setViewportView(Component view)设置在滚动面板中显示的组件对象setHorizontalScrollBarPolicy(int policy)设置水平滚动条的显示策略setVerticalScrollBarPolicy(int policy)设置垂直滚动条的显示策略setWheelScrollingEnabled(false)设置滚动面板的滚动条是否支持鼠标的滚动轮课件制作人:XXXJScro

303、llPane面板在调用上表中设置滚动条显示策略方法设置滚动条的显示策略时,方法的参数可以选择JScrollPane类中设置滚动条显示策略的静态常量,如下表所示。【例8-16】静 态 常 量常 量 值滚动条的显示策略HORIZONTAL_SCROLLBAR_AS_NEEDED30设置水平滚动条为只在需要时显示,默认策略HORIZONTAL_SCROLLBAR_NEVER31设置水平滚动条为永远不显示HORIZONTAL_SCROLLBAR_ALWAYS32设置水平滚动条为一直显示VERTICAL_SCROLLBAR_AS_NEEDED20设置垂直滚动条为只在需要时显示,默认策略VERTICAL_

304、SCROLLBAR_NEVER21设置垂直滚动条为永远不显示VERTICAL_SCROLLBAR_ALWAYS22设置垂直滚动条为一直显示课件制作人:XXXJScrollPane面板在开发应用程序时,对事件的处理是必不可少的,只有这样才能够实现软件与用户的交互。常用事件有包括:n动作事件处理n焦点事件处理n鼠标事件处理n键盘事件处理课件制作人:XXX8.6.1动作事件处理动作事件由ActionEvent类定义,最常用的是当单击按钮后将产生动作事件,可以通过实现ActionListener接口处理相应的动作事件。ActionListener接口只有一个抽象方法,将在动作发生后被触发,例如单击按钮

305、之后,ActionListener接口的具体定义如下:publicinterfaceActionListenerextendsEventListenerpublicvoidactionPerformed(ActionEvente);课件制作人:XXX动作事件处理ActionEvent类中有两个比较常用的方法:(1)getSource():用来获得触发此次事件的组件对象,返回值类型为Object;(2)getActionCommand():用来获得与当前动作相关的命令字符串,返回值类型为String。【例8-17】课件制作人:XXX8.6.2焦点事件处理焦点事件由FocusEvent类捕获,所有

306、的组件都能产生焦点事件,可以通过实现FocusListener接口处理相应的动作事件。FocusListener接口有两个抽象方法,分别在组件获得或失去焦点时被触发,FocusListener接口的具体定义如下:FocusEvent类中比较常用的方法是getSource(),用来获得触发此次事件的组件对象,返回值类型为Object。【例8-18】publicinterfaceFocusListenerextendsEventListenerpublicvoidfocusGained(FocusEvente);/当组件获得焦点时将触发该方法publicvoidfocusLost(FocusEve

307、nte);/当组件失去焦点时将触发该方法课件制作人:XXX8.6.3鼠标事件处理鼠标事件由MouseEvent类捕获,所有的组件都能产生鼠标事件,可以通过实现MouseListener接口处理相应的鼠标事件。MouseListener接口有5个抽象方法,分别在光标移入(出)组件时、鼠标按键被按下(释放)时和发生单击事件时被触发。所谓单击事件,就是按键被按下并释放。需要注意的是,如果按键是在移出组件之后才被释放,则不会触发单击事件。课件制作人:XXX鼠标事件处理MouseListener接口的具体定义如下:publicinterfaceMouseListenerextendsEventListe

308、ner/光标移入组件时被触发publicvoidmouseEntered(MouseEvente);/鼠标按键被按下时触发publicvoidmousePressed(MouseEvente);/鼠标按键被释放时触发publicvoidmouseReleased(MouseEvente);/发生单击事件时被触发publicvoidmouseClicked(MouseEvente);/光标移出组件时被触发publicvoidmouseExited(MouseEvente);课件制作人:XXX鼠标事件处理MouseEvent类中比较常用的方法如下表所示。可以通过下表中的静态常量,判断通过getBu

309、tton()方法得到的值代表哪个键。【例8-19】方 法功 能getSource()用来获得触发此次事件的组件对象,返回值为Object类型getButton()用来获得代表触发此次按下、释放或单击事件的按键的int型值getClickCount()用来获得单击按键的次数静 态 常 量常 量 值代 表 的 键BUTTON11代表鼠标左键BUTTON22代表鼠标滚轮BUTTON33代表鼠标右键课件制作人:XXX8.6.4键盘事件处理键盘事件由KeyEvent类捕获,最常用的是当向文本框输入内容时将发生键盘事件,可以通过实现KeyListener接口处理相应的键盘事件。KeyListener接口有

310、3个抽象方法,分别在发生击键事件、键被按下和释放时被触发,FocusListener接口的具体定义如下:publicinterfaceKeyListenerextendsEventListenerpublicvoidkeyTyped(KeyEvente);publicvoidkeyPressed(KeyEvente);publicvoidkeyReleased(KeyEvente);课件制作人:XXX键盘事件处理KeyEvent类中比较常用的方法如下表所示:在KeyEvent类中以“VK_”开头的静态常量代表各个按键的keyCode,可以通过这些静态常量判断事件中的按键,以及获得按键的标签。【

311、例8-20】方 法功 能getSource()用来获得触发此次事件的组件对象,返回值为Object类型getKeyChar()用来获得与此事件中的键相关联的字符getKeyCode()用来获得与此事件中的键相关联的整数keyCodegetKeyText(int keyCode)用来获得描述keyCode的标签,例如“A”、“F1”、“HOME”等isActionKey() 用来查看此事件中的键是否为“动作”键isControlDown()用来查看“Ctrl”键在此次事件中是否被按下isAltDown()用来查看“Alt”键在此次事件中是否被按下isShiftDown()用来查看“Shift”键

312、在此次事件中是否被按下JSP程序设计教程课件 制作人:XXXJava实用教程第9章Applet程序设计课件制作人:XXX第9章Applet程序设计9.1Applet概述9.2Applet基础9.3图像处理9.4音频播放9.5HTML的Applet标签和属性9.6JAR文件9.7为Applet传递参数9.8JavaScript操作Applet9.9控制其他Applet程序9.10Applet安全基础课件制作人:XXX9.2Applet基础Applet类继承了Panel类,是一个容器,在Applet程序开发中多使用JApplet类,它是JavaSwing中的成员,继承了Applet类,JApple

313、t类的继承关系如下图所示。JApplet和JavaSwing中的JFrame窗体类似,可以容纳各种组件,例如按钮、标签、列表框、文本框等。课件制作人:XXX9.2.1简单Applet实例在讲解Applet程序设计之前,先来看一个简单的HelloWorld实例,该实例以最简单的Applet程序结构演示了Applet的运行步骤。【例9-1】课件制作人:XXX9.2.2Applet生命周期Applet程序没有main()方法,它是在init()方法中创建并使用组件的,该方法用于初始化Applet程序,它也是Applet声明周期的第一个阶段。Applet声明周期包括4个阶段。(1)init()方法Ap

314、plet程序的初始化阶段会调用该方法,实现程序初始化。(2)start()方法Applet程序的开始阶段,当完成Applet的初始化以后,将会执行该方法,当用户从其他页码返回到包含该Applet程序的页面时,也会执行该方法,所以该方法会被多次调用,而init()方法只能执行一次初始化任务。start()方法多用于恢复线程等操作。课件制作人:XXXApplet生命周期(3)stop()方法Applet程序的暂停阶段,当用户离开包含Applet的页面时,将调用该方法。同start()方法类似,如果用户从其他页面返回到包含该Applet程序的页面时,该方法也会被执行,所以stop()方法会被执行多次

315、。该方法多用在线程挂起、停止某些耗时或者消耗资源的操作上,以节省系统资源,保证系统的运行速度。(4)destroy()方法Applet程序的销毁阶段,该方法仅在用户正常关闭浏览器时被调用,它用于Applet被结束之前,释放程序所占用的资源和执行程序结束时的任务。这4个生命周期的方法不应该直接调用,它们由Applet程序自动执行,程序设计人员需要做的就是根据需要覆盖其中的某个方法,例如覆盖init()方法初始化程序界面。【例9-2】课件制作人:XXX9.2.3Graphics类Applet程序中除了使用Swing组件显示界面之外,还可以使用Graphics类提供的各种方法,在Applet程序中绘

316、制多种图形、图片和文字等。在学习Applet程序开发之前,首先需要了解一下使用Graphics类绘制文本和图片的方法。课件制作人:XXXGraphics类绘制图片绘制图片,就是在Applet容器中显示一个事先准备好的图片资源。绘制图片由drawImage()方法实现,该方法有多种重载,它们可以指定绘制图片的位置和大小。(1)重载方法1语法格式为:img:该参数是要绘制的图片对象,如果该参数为null,那么该方法不做任何操作。x:绘制图片的x坐标。y:绘制图片的y坐标。observer:绘制图片需要通知的对象,一般设置为Applet本身即可。drawImage(Imageimg,intx,int

317、y,ImageObserverobserver)课件制作人:XXXGraphics类绘制图片例如在Applet程序中绘制一幅图片,图片的起始x、y坐标分别是x=20,y=10。可以使用如下代码:其中最后一条语句中的“this”关键字是Applet本身。drawImage()方法的重载,在成功绘制图片之后都会返回布尔值true,否则返回false。privateImageback;/背景图片back=getImage(getCodeBase(),back.jpg);/获取图片实例Graphicsg=getGraphics();/获取Graphics类的实例g.drawImage(back,20,

318、10,this)/绘制图片课件制作人:XXXGraphics类绘制图片(2)重载方法2语法格式为:width:该参数指定图片显示的宽度。height:该参数指定图片显示的高度,这两个参数可以实现图片的缩放。publicabstractbooleandrawImage(Imageimg,intx,inty,intwidth,intheight,ImageObserverobserver)课件制作人:XXXGraphics类绘制文本使用Graphics类绘制文本字符串,也是最常用的方法,可以使用drawString()方法在程序指定的位置显示指定的文本信息。语法格式为:str:将要绘制的文本信息。

319、x:水平坐标。y:垂直坐标。例如Applet程序在x,y坐标分别为20像素和10像素的位置绘制文本内容“新年快乐”,可以使用如下代码:Graphicsg=getGraphics();Stringmessage=新年快乐;g.drawString(message,20,10);drawString(Stringstr,intx,inty)课件制作人:XXX9.3图像处理在开发JavaSwing桌面应用程序时,可以使用绝对路径直接加载图片文件,但是在Web应用中的路径是以URL为基础的,所以Applet程序必须配合URL类才能正确找到资源文件。创建URL类的实例可能会抛出异常,必须捕获并处理该异常

320、,以使程序能继续运行。一般格式为:tryURLurl=newURL(http:/localhost);catch(MalformedURLExceptione)e.printStackTrace();课件制作人:XXX图像处理在Applet程序中获取图片资源使用getImage()方法,该方法有两个重载方法。(1)使用URL绝对路径可以根据URL路径获取Image图片对象,但是这个URL必须是图片文件的绝对路径。语法格式为:url:图片文件的URL路径,该路径必须是指定图片文件位置的绝对路径。getImage(URLurl)课件制作人:XXX图像处理例如使用网站URL路径“http:/ 性 值

321、说 明left使Applet程序在网页中左对齐,后面的文本环绕在Applet程序右侧right使Applet程序在网页中右对齐,后面的文本环绕在Applet程序左侧top在网页中使Applet程序顶部与当前行顶部对齐middle在网页中使Applet程序中部与当前行的基线对齐absmiddle在网页中使Applet程序中部与当前行的中部对齐,请区别于middlebottom在网页中使Applet程序底部与当前行文本的底部对齐absbottom在网页中使Applet程序底部与当前行底部对齐,请区别于bottomtexttop在网页中使Applet程序顶部与当前行文本顶部对齐,请区别于topbas

322、eline在网页中使Applet程序底部与当前行的基线对齐课件制作人:XXXHTML的Applet标签和属性(5)vspace属性与hspace属性这两个属性分别用于设置Applet程序在上下垂直方向空白的像素数目,和Applet程序在左右水平方向空白的像素数目。例如使Applet程序左对齐,并且上下空白50像素,左右空白100像素,可以使用如下的HTML代码:课件制作人:XXXHTML的Applet标签和属性(6)codebase属性该属性用于指定Applet程序的路径,该路径相对与当前HTML网页文件,例如“Hello.class”类文件位于myApplets文件夹中,可以使用如下代码加载

323、Applet:code属性只用于指定Applet程序名称,例如com.lzw.Hello.class,而codebase属性则用于指定Applet程序的位置,当指定了codebase属性之后,code属性指定的程序名称,不再相对于当前HTML文件,而是相对于codebase属性指定的程序位置,但是codebase属性则相对与当前HTML文件的位置。课件制作人:XXXHTML的Applet标签和属性(7)archive属性该属性可以指定包含Applet程序的JAR文件,JAR文件是Java程序的打包文件,它采用ZIP格式将程序压缩,使Java程序的体积大幅度缩小,这样,在浏览包含Applet程序

324、的网页时,Applet程序的下载时间相对缩短,从而提高程序运行速度。(8)name属性该属性为Applet程序指定名称,使网页脚本可以通过改名成获取Applet程序实例,并使用该实例操作Applet程序。课件制作人:XXX9.6JAR文件JAR文件是Java的打包文件,它可以将多个编译后的类文件和图片、音频、视频、文本、属性等资源封装到一个JAR文件中。JAR使用ZIP压缩格式存储数据,它的体积更小,在网络中的传输更快捷。另外导致网络传输速度下降的原因与创建多个文件的连接有关,如果一个Applet程序由4个或更多的类组成,在执行该Applet程序时,将会建立多个文件的连接,而浏览器与Web服务

325、器建立连接很耗费时间,如果将该程序打包成一个JAR文件,只需建立一个文件连接,便可以执行Applet程序,而且JAR文件压缩了数据,体积小了很多,所以下载的时间也更短。HTML中的标签也使用archive属性,提供了对JAR文件的支持,该属性指定封装Applet程序的JAR文件,当浏览包含Applet程序的网页时,首先下载该JAR文件,然后从JAR文件中获取Applet程序代码和涉及的资源。课件制作人:XXX9.6.1使用JDK工具生成JAR在安装好JDK以后,在JDK的安装文件夹中包含bin子文件夹,该文件夹中包含了编译、调试和运行Java程序的多种工具,其中“jar.exe”文件是JAR文

326、件打包工具,使用该工具可以创建JAR文件并封装各种资源文件和编译好的Java文件。一般格式为:cvf:该参数用于生成JAR压缩文档并输出详细信息。jarName:该参数用于指定JAR文件名称。file1:添加到JAR文件中的第一个文件。file2:添加到JAR文件中的第二个文件(可以使用通配符指定多个文件,也可以在file2参数后再指定其他文件)。jarcvfjarNamefile1file2课件制作人:XXX9.6.2使用Eclipse开发工具生成JAR现在的应用程序、操作系统、开发工具逐渐图形化,而且有很多的命令由于参数过多难以记忆,使用开发工具完成JAR文件的创建已经是最常用的一种方式。

327、Eclipse作为一个强大的Java开发工具,不但提供了Java源程序的代码辅助、智能纠错、动态调试等环境,而且还可以直接将程序代码导出成为一个JAR文档文件。具体操作步骤如下。课件制作人:XXX9.6.3使用JAR文件中的Applet程序将程序制作成JAR文件之后,在HTML的标签中访问JAR文件中的Applet程序可以使用如下HTML代码:标签使用archive属性指定了“AudioPlay.jar”文件,Applet程序在运行时期,会先下载该JAR文件,然后运行JAR文件中的ImgPlayer.class类文件。课件制作人:XXX9.7为Applet传递参数HTML的标签可以为Apple

328、t程序设置各种初始属性,例如宽度、高度、对齐方式等,但是有些情况下,Applet程序需要根据参数初始化自己,这可以通过标签的子标签来实现。一般格式为:name:该参数用于设置传递给Applet程序的参数名称。value:该参数用于设置传递给Applet程序的参数值。课件制作人:XXX为Applet传递参数在Applet程序中可以使用getParameter()方法获取标签提供的参数。语法格式为:arg:该参数是标签设置的参数名称。例如,获取标签设置的商品单价参数“price”,可以使用如下代码:【例9-5】publicvoidinit()StringpriceArg=getParameter(

329、price);floatprice=Float.parseFloat(priceArg);getParameter(Stringarg)课件制作人:XXX9.8JavaScript操作AppletHTML的标签可以使用name属性为Applet程序命名,这样JavaScript脚本就可以获取Applet程序的实例,并调用Applet程序的方法执行相关操作。【例9-6】课件制作人:XXX9.9控制其他Applet程序Applet上下文是实现AppletContext接口的对象。通过该对象可以实现获取同一个网页中的所有Applet程序、在浏览器状态栏中显示信息、显示指定URL的网页等。获取Appl

330、et上下文需要使用getAppletContext()方法。一般格式为:Applet上下文提供了获取其他Applet程序实例的方法,这样就可以控制获取的Applet程序实例,从而实现对其他Applet程序的控制。Applet上下文中获取其他Applet程序的方法有两种。AppletContextappletContext=getAppletContext();课件制作人:XXX控制其他Applet程序(1)getApplets()方法getApplets()方法用于获取包含在同一个上下文中的所有Applet程序,该方法返回一个枚举类型的实例,这个枚举类型中包含了同一个上下文中的其他Applet

331、程序的引用。语法格式为:appletContext:这是一个Applet上下文对象。Enumerationapplets=appletContext.getApplets();课件制作人:XXX控制其他Applet程序(2)getApplets(Stringname)方法getApplets()方法用于获取同一个上下文中指定名称的Applet程序,该方法返回一个Applet程序的引用。语法格式为:appletContext:这是一个Applet上下文对象。name:该参数是另外一个Applet程序的名称。【例9-7】appletContext.getApplet(Stringname);课件制

332、作人:XXX9.10Applet安全基础Applet程序存放在远程服务器端,当用于浏览服务器的网页时,将自动下载该Applet程序,然后在本地执行,如果有人使用Applet程序编写恶意程序,对用户主机进行攻击,或盗取用户资料,例如银行账号、密码等信息,将对用户造成极大地损害。所以,安全成为Applet至关重要的问题。课件制作人:XXX9.10.1Applet的行为Applet程序可以运行在任何一个平台(即操作系统)中,在不同的平台上可以实现相同的功能,这些功能包括:(1)显示图片;(2)播放音频;(3)获取用户的鼠标、键盘操作事件;(4)把用户输入的信息提交给服务器。这些功能对于网站信息提示、

333、图片处理、在线交互、提交订单等业务来讲,已经足够完成网站中的各种任务。所以,对于其他操作必须加以限制,例如访问本地文件、获取用户和系统信息等操作。课件制作人:XXX9.10.2Applet的安全限制Applet拥有安全管理器,它为程序提供了足够的安全保障,当Applet程序违反安全规则时,Applet安全管理器将抛出SecurityException异常,Applet有以下安全限制。(1)不允许执行任何本地程序。(2)不允许对本地文件进行读写操作。(3)在Applet弹出窗口中都会带有一个警告信息。(4)只能获取少量的计算机信息,例如Java虚拟机的版本、操作系统版本与名称,还有文件分隔符、换

334、行符等特殊字符。(5)不能获取用户名、E-mail地址等信息。(6)Applet不能与其他服务器通信,只能与存放Applet程序的服务器进行通信。JSP程序设计教程课件 制作人:XXXJava实用教程第10章网络程序设计课件制作人:XXX第10章网络程序设计10.1基础知识10.2IP地址封装10.3套接字10.4数据报10.5网络聊天课件制作人:XXX10.1基础知识要开发网络应用程序,就必须对网络的基础知识有一定的了解,Java的网络通信可以使用TCP、IP、UDP等协议,在学习Java网络程序设计之前,先简单了解一下有关协议的基础知识。课件制作人:XXX10.1.1TCPTCP的全称是T

335、ransmissionControlProtocol,也就是传输控制协议,主要负责数据的分组和重组。它与IP协议组合使用,称为TCP/IP。TCP适合于对可靠性比较高的运行环境,因为TCP是严格的、安全的。它以固定连接为基础,提供计算机之间可靠的数据传输,计算机之间可以凭借连接交换数据,并且传送的数据能够正确抵达目标,传送到目标后的数据仍然保持数据送出时的顺序。课件制作人:XXX10.1.2UDPUDP的全称是UserDatagramProtocol,也就是用户数据报协议,和TCP不同,UDP是一种非持续连接的通信协议,它不保证数据能够正确抵达目标。虽然UDP可能会因网络连接等各种原因,无法保

336、证数据的安全传送,而且多个数据包抵达目标的顺序可能和发送时的顺序不同,但是它比TCP更轻量一些,TCP的认证会耗费额外的资源,可能导致传输速度的下降。在正常的网络环境中,数据都可以安全的抵达目标计算机中,所以使用UDP会更加适合一些对可靠性要求不高的环境,例如在线影视、聊天室等。课件制作人:XXX10.2IP地址封装IP地址是每个计算机在网络中的唯一标识,它是32位或128位的无符号数字,使用4组数字表示一个固定的编号,例如“192.168.128.255”就是局域网络中的编号。IP地址,它是一种低级协议,UDP和TCP都是在它的基础上构建的。Java提供了IP地址的封装类InetAddres

337、s。它封装了IP地址,并提供了相关的常用方法,例如解析IP地址的主机名称、获取本机IP地址的封装、测试IP地址是否可达等课件制作人:XXXIP地址封装InetAddress类的常用方法如表10-1所示。【例10-1】方 法 名 称方 法 说 明返 回 类 型getLocalHost()返回本地主机的InetAddress对象InetAddressgetByName(String host)获取指定主机名称的IP地址InetAddressgetHostName()获取此主机名StringgetHostAddress()获取主机IP地址StringisReachable(int timeout)在

338、timeout指定的毫秒时间内,测试IP地址是否可达boolean课件制作人:XXX10.3套接字套接字(Socket)是代表计算机之间网络连接的对象,用于建立计算机之间的TCP连接。它提供了多种方法,使计算机之间可以建立连接并实现网络通信。课件制作人:XXX10.3.1服务器端套接字服务器端的套接字是ServerSocket类的实例对象,用于实现服务器程序,ServerSocket类将监视指定的端口,并建立客户端到服务器端套接字的连接,也就是客户负责呼叫任务。课件制作人:XXX服务器端套接字(创建服务器端套接字)创建服务器端套接字可以使用4种构造方法。(1)ServerSocket()默认构

339、造方法,可以创建未绑定端口号的服务器套接字。服务器套接字的所有构造方法都需要处理IOException异常。一般格式为:tryServerSocketserver=newServerSocket();catch(IOExceptione)e.printStackTrace();课件制作人:XXX服务器端套接字(创建服务器端套接字)(2)ServerSocket(intport)该构造方法将创建绑定到port参数指定端口的服务器套接字对象,默认的最大连接队列长度为50,也就是说如果连接数量超出50个,将不会再接收新的连接请求。一般格式为:tryServerSocketserver=newServ

340、erSocket(9527);catch(IOExceptione)e.printStackTrace();课件制作人:XXX服务器端套接字(创建服务器端套接字)(3)ServerSocket(intport,intbacklog)使用port参数指定的端口号和backlog参数指定的最大连接队列长度创建服务器端套接字对象,这个构造方法可以指定超出50的连接数量,例如300。一般格式为:tryServerSocketserver=newServerSocket(9527,300);catch(IOExceptione)e.printStackTrace();课件制作人:XXX服务器端套接字(创

341、建服务器端套接字)(4)publicServerSocket(intport,intbacklog,InetAddressbindAddr)使用port参数指定的端口号和backlog参数指定的最大连接队列长度创建服务器端套接字对象,如果服务器有多个IP地址,可以使用bindAddr参数指定创建服务器套接字的IP地址。一般格式为:tryInetAddressaddress=InetAddress.getByName(192.168.1.128);ServerSocketserver=newServerSocket(9527,300,address);catch(IOExceptione)e.p

342、rintStackTrace();课件制作人:XXX服务器端套接字(接受套接字连接)当服务器建立ServerSocket套接字对象以后,就可以使用该对象的accept()方法接受客户端请求的套接字连接。语法格式为:该方法被调用之后,将等待客户的连接请求,在接收到客户端的套接字连接请求以后,该方法将返回Socket对象,这个Socket对象是已经和客户端建立好连接的套接字,可以通过这个Socket对象获取客户端的输入输出流来实现数据发送与接收。serverSocket.accept()课件制作人:XXX服务器端套接字(接受套接字连接)该方法可能会产生IOException异常,所以在调用acce

343、pt()方法时必须捕获并处理该异常。一般格式为:accept()方法将阻塞当前线程,直到接收到客户端的连接请求为止,该方法之后的任何语句都不会被执行,必须有客户端发送连接请求;accept()方法返回Socket套接字以后,当前线程才会继续运行,accept()方法之后的程序代码才会被执行。tryserver.accept();catch(IOExceptione)e.printStackTrace();课件制作人:XXX10.3.2客户端套接字Socket类是实现客户端套接字的基础。它采用TCP建立计算机之间的连接,并包含了Java语言所有对TCP有关的操作方法,例如建立连接、传输数据、断开

344、连接等。课件制作人:XXX客户端套接字(创建客户端套接字)Socket类定义了多个构造方法,它们可以根据InetAddress对象或者字符串指定的IP地址和端口号创建实例。下面介绍一下Socket常用的4个构造方法。课件制作人:XXX客户端套接字(创建客户端套接字)(1)Socket(InetAddressaddress,intport)使用address参数传递的IP封装对象和port参数指定的端口号创建套接字实例对象。Socket类的构造方法可能会产生UnknownHostException和IOException异常,在使用该构造方法创建Socket对象时必须捕获和处理这两个异常。一般格

345、式为:tryInetAddressaddress=InetAddress.getByName(LZW); /创建IP封装类intport=33;/定义端口号Socketsocket=newSocket(address,port);/创建套接字catch(UnknownHostExceptione)e.printStackTrace();catch(IOExceptione)e.printStackTrace();课件制作人:XXX客户端套接字(创建客户端套接字)(2)Socket(Stringhost,intport)使用host参数指定的IP地址字符串和port参数指定的整数类型端口号创建套

346、接字实例对象。一般格式为:trySocketsocket=newSocket(192.168.1.1,33);catch(UnknownHostExceptione)e.printStackTrace();catch(IOExceptione)e.printStackTrace();课件制作人:XXX客户端套接字(创建客户端套接字)(3)Socket(InetAddressaddress,intport,InetAddresslocalAddr,intlocalPort)创建一个套接字并将其连接到指定远程地址的指定远程端口。一般格式为:tryInetAddresslocalHost=InetA

347、ddress.getLocalHost();InetAddressaddress=InetAddress.getByName(192.168.1.1);Socketsocket=newSocket(address,33,localHost,44);catch(UnknownHostExceptione)e.printStackTrace();catch(IOExceptione)e.printStackTrace();课件制作人:XXX客户端套接字(创建客户端套接字)(4)Socket(Stringhost,intport,InetAddresslocalAddr,intlocalPort)创

348、建套接字并将其连接到指定远程主机上的指定远程端口一般格式为:【例10-2】tryInetAddresslocalHost=InetAddress.getLocalHost();Socketsocket=newSocket(192.168.1.1,33,localHost,44);catch(UnknownHostExceptione)e.printStackTrace();catch(IOExceptione)e.printStackTrace();课件制作人:XXX客户端套接字(发送和接收数据)Socket对象创建成功以后,代表和对方的主机已经建立了连接,可以接收和发送数据了。Socket提

349、供了两个方法分别获取套接字的输入流和输出流,可以将要发送的数据写入输出流,实现发送功能,或者从输入流读取对方发送的数据,实现接收功能。(1)接收数据Socket对象从数据输入流中获取数据,该输入流中包含对方发送的数据,这些数据可能是文件、图片、音频或视频。所以,在实现接收数据之前,必须使用getInputStream()方法获取输入流。语法格式为:socket:套接字实例对象。socket.getInputStream()课件制作人:XXX客户端套接字(发送和接收数据)(2)发送数据Socket对象使用输出流,向对方发送数据,所以,在实现数据发送之前,必须使用getOutputStream()

350、方法获取套接字的输出流。语法格式为:socket:套接字实例对象。【例10-3】socket.getOutputStream()课件制作人:XXX10.4数据报Java语言可以使用TCP和UDP两种通信协议实现网络通信,其中TCP通信由Socket套接字实现,而UDP通信需要使用DatagramSocket类实现。UDP传递信息的速度更快,但是没有TCP的高可靠性,当用户通过UDP发送信息之后,无法确定能否正确的传送到目的地。虽然UDP是一种不可靠的通信协议,但是大多数场合并不需要严格的、高可靠性的通信,它们需要的是快速的信息发送,并能容忍一些小的错误,那么使用UDP通信来实现会更合适一些。U

351、DP将数据打包,也就是通信中所传递的数据包,然后将数据包发送到指定目的地,对方会接收数据包,然后查看数据包中的数据。课件制作人:XXX10.4.1DatagramPacket该类是UDP所传递的数据包,即打包后的数据。数据包用来实现无连接包投递服务。每个数据包仅根据包中包含的信息从一台计算机传送到另一台计算机,传送的多个包可能选择不同的路由,也可能按不同的顺序到达。DatagramPacket类提供了多个构造方法用于创建数据包的实例,下面介绍最常用的两个。课件制作人:XXXDatagramPacket(1)DatagramPacket(bytebuf,intlength)该构造方法用来创建数据

352、包实例,这个数据包实例将接收长度为length的数据包。语法格式为:buf:保存传入数据报的缓冲区。len:要读取的字节数。DatagramPacket(bytebuf,intlength)课件制作人:XXXDatagramPacket(2)DatagramPacket(bytebuf,intlength,InetAddressaddress,intport)创建数据报包实例,用来将长度为length的数据包发送到address参数指定地址和port参数指定端口号的主机。length参数必须小于等于buf数组的长度。语法格式为:buf:包数据。length:包长度。address:目的地址。p

353、ort:目的端口号。DatagramPacket(bytebuf,intlength,InetAddressaddress,intport)课件制作人:XXX10.4.2DatagramSocket该类是用于发送和接收数据的数据报套接字。数据报套接字是数据包传送服务的发送或接收点。要实现UDP通信的数据发送就必须创建数据报套接字。DatagramSocket类提供了多个构造方法用于创建数据报套接字,下面介绍最常用的3个构造方法。课件制作人:XXXDatagramSocket(1)DatagramSocket()默认的构造方法,该构造方法将使用本机任何可用的端口创建数据报套接字实例。在创建Dat

354、agramSocket类的实例时,有可能会产生SocketException异常,所以在创建数据报套接字时,应该捕获并处理该异常。一般格式为:tryDatagramSocketdsocket=newDatagramSocket();catch(SocketExceptione)e.printStackTrace();课件制作人:XXXDatagramSocket(2)DatagramSocket(intport)创建数据报套接字并将其绑定到port参数指定的本机端口,端口号取值必须在065535(包括两者)。一般格式为:tryDatagramSocketdsocket=newDatagramS

355、ocket(9527);catch(SocketExceptione)e.printStackTrace();课件制作人:XXXDatagramSocket(3)DatagramSocket(intport,InetAddressladdr)创建数据报套接字,将其绑定到laddr参数指定的本机地址和port参数指定的本机端口号。本机端口号取值必须在065535之间(包括两者)。一般格式为:在了解了DatagramPacket类和DatagramSocket类之后,就可以使用这两个类实现UDP通信程序设计。【例10-4】tryInetAddresslocalHost=InetAddress.ge

356、tLocalHost();DatagramSocketdsocket=newDatagramSocket(9527,localHost);catch(SocketExceptione)e.printStackTrace();catch(UnknownHostExceptione)e.printStackTrace();JSP程序设计教程课件 制作人:XXXJava实用教程第11章JDBC数据库编程课件制作人:XXX第11章JDBC数据库编程11.1JDBC概述11.2JDBC中的常用接口11.3连接数据库11.4操作数据库10.5网络聊天11.5应用JDBC事务课件制作人:XXX11.2JDB

357、C中的常用接口JDBC提供了众多的接口和类,通过这些接口和类,可以实现与数据库的通信,本节将详细介绍一些常用的JDBC接口和类。课件制作人:XXX11.2.1Driver接口每种数据库的驱动程序都应该提供一个实现java.sql.Driver接口的类,简称Driver类,在加载某一驱动程序的Driver类时,它应该创建自己的实例并向java.sql.DriverManager类注册该实例。通常情况下通过java.lang.Class类的静态方法forName(StringclassName),加载欲连接数据库的Driver类,该方法的入口参数为欲加载Driver类的完整路径。成功加载后,会将D

358、river类的实例注册到DriverManager类中,如果加载失败,将抛出ClassNotFoundException异常,即未找到指定Driver类的异常。课件制作人:XXX11.2.2DriverManager类java.sql.DriverManager类负责管理JDBC驱动程序的基本服务,是JDBC的管理层,作用于用户和驱动程序之间,负责跟踪可用的驱动程序,并在数据库和驱动程序之间建立连接;另外,DriverManager类也处理诸如驱动程序登录时间限制及登录和跟踪消息的显示等工作。成功加载Driver类并在DriverManager类中注册后,DriverManager类即可用来建

359、立数据库连接。当调用DriverManager类的getConnection()方法请求建立数据库连接时,DriverManager类将试图定位一个适当的Driver类,并检查定位到的Driver类是否可以建立连接,如果可以则建立连接并返回,如果不可以则抛出SQLException异常。课件制作人:XXXDriverManager类DriverManager类提供的常用静态方法如下表所示:方 法 名 称功 能 描 述getConnection(String url, String user, String password)用来获得数据库连接,3个入口参数依次为要连接数据库的URL、用户名和密

360、码,返回值的类型为java.sql.ConnectionsetLoginTimeout(int seconds)用来设置每次等待建立数据库连接的最长时间setLogWriter(java.io.PrintWriter out)用来设置日志的输出对象println(String message)用来输出指定消息到当前的JDBC日志流课件制作人:XXX11.2.3Connection接口java.sql.Connection接口代表与特定数据库的连接,在连接的上下文中可以执行SQL语句并返回结果,还可以通过getMetaData()方法获得由数据库提供的相关信息,例如数据表、存储过程和连接功能等信

361、息。Connection接口提供的常用方法如下表所示。课件制作人:XXX方 法 名 称功 能 描 述createStatement()创建并返回一个Statement实例,通常在执行无参的SQL语句时创建该实例prepareStatement()创建并返回一个PreparedStatement实例,通常在执行包含参数的SQL语句时创建该实例,并对SQL语句进行了预编译处理prepareCall()创建并返回一个CallableStatement实例,通常在调用数据库存储过程时创建该实例setAutoCommit()设置当前Connection实例的自动提交模式。默认为true,即自动将更改同步

362、到数据库中;如果设为false,需要通过执行commit()或rollback()方法手动将更改同步到数据库中getAutoCommit()查看当前的Connection实例是否处于自动提交模式,如果是则返回true,否则返回falsesetSavepoint()在当前事务中创建并返回一个Savepoint实例,前提条件是当前的Connection实例不能处于自动提交模式,否则将抛出异常releaseSavepoint()从当前事务中移除指定的Savepoint实例setReadOnly()设置当前Connection实例的读取模式,默认为非只读模式。不能在事务当中执行该操作,否则将抛出异常。

363、有一个boolean型的入口参数,设为true表示开启只读模式,设为false表示关闭只读模式isReadOnly()查看当前的Connection实例是否为只读模式,如果是则返回true,否则返回falseisClosed()查看当前的Connection实例是否被关闭,如果被关闭则返回true,否则返回falsecommit()将从上一次提交或回滚以来进行的所有更改同步到数据库,并释放Connection实例当前拥有的所有数据库锁定rollback()取消当前事务中的所有更改,并释放当前Connection实例拥有的所有数据库锁定。该方法只能在非自动提交模式下使用,如果在自动提交模式下执行

364、该方法,将抛出异常。有一个参数为Savepoint实例的重载方法,用来取消Savepoint实例之后的所有更改,并释放对应的数据库锁定close()立即释放Connection实例占用的数据库和JDBC资源,即关闭数据库连接课件制作人:XXX11.2.4Statement接口java.sql.Statement接口用来执行静态的SQL语句,并返回执行结果。例如,对于INSERT、UPDATE和DELETE语句,调用executeUpdate(Stringsql)方法;对于SELECT语句,则调用executeQuery(Stringsql)方法,并返回一个永远不能为null的ResultSet

365、实例。Statement接口提供的常用方法如下表所示。课件制作人:XXX方 法 名 称功 能 描 述executeQuery(String sql)执行指定的静态SELECT语句,并返回一个永远不能为null的ResultSet实例executeUpdate(String sql)执行指定的静态INSERT、UPDATE或DELETE语句,并返回一个int型数值,此数为同步更新记录的条数clearBatch()清除位于Batch中的所有SQL语句。如果驱动程序不支持批量处理将抛出异常addBatch(String sql)将指定的SQL命令添加到Batch中。String型入口参数通常为静态的

366、INSERT或UPDATE语句。如果驱动程序不支持批量处理将抛出异常executeBatch()执行Batch中的所有SQL语句,如果全部执行成功,则返回由更新计数组成的数组,数组元素的排序与SQL语句的添加顺序对应。数组元素有以下几种情况:大于或等于零的数:说明SQL语句执行成功,此数为影响数据库中行数的更新计数;:说明SQL语句执行成功,但未得到受影响的行数:说明SQL语句执行失败,仅当执行失败后继续执行后面的SQL语句时出现。如果驱动程序不支持批量、或者未能成功执行Batch中的SQL语句之一,将抛出异常close()立即释放Statement实例占用的数据库和JDBC资源课件制作人:X

367、XX11.2.5PreparedStatement接口java.sql.PreparedStatement接口继承并扩展了Statement接口,用来执行动态的SQL语句,即包含参数的SQL语句。通过PreparedStatement实例执行的动态SQL语句将被预编译并保存到PreparedStatement实例中,从而可以反复并且高效地执行该SQL语句。需要注意的是,在通过setXxx()方法为SQL语句中的参数赋值时,建议利用与参数类型匹配的方法,也可以利用setObject()方法为各种类型的参数赋值。PreparedStatement接口的使用方法如下:PreparedStatemen

368、t接口提供的常用方法如下表所示。PreparedStatementps=connection.prepareStatement(select*fromtable_namewhereid?and(name=?orname=?);ps.setInt(1,6);ps.setString(2,马先生);ps.setObject(3,李先生);ResultSetrs=ps.executeQuery();课件制作人:XXX方 法 名 称功 能 描 述executeQuery()执行前面定义的动态SELECT语句,并返回一个永远不能为null的ResultSet实例executeUpdate()执行前面定义

369、的动态INSERT、UPDATE或DELETE语句,并返回一个int型数值,为同步更新记录的条数SetInt(int i, int x)为指定参数设置int型值,对应参数的SQL类型为INTEGERsetLong(int i, long x)为指定参数设置long型值,对应参数的SQL类型为BIGINTsetFloat(int i, float x)为指定参数设置float型值,对应参数的SQL类型为FLOATsetDouble(int i, double x)为指定参数设置double型值,对应参数的SQL类型为DOUBLEsetString(int i, String x)为指定参数设置S

370、tring型值,对应参数的SQL类型为VARCHAR或LONGVARCHARsetBoolean(int i, boolean x)为指定参数设置boolean型值,对应参数的SQL类型为BITsetDate(int i, Date x)为指定参数设置java.sql.Date型值,对应参数的SQL类型为DATEsetObject(int i, Object x)用来设置各种类型的参数,JDBC规范定义了从Object类型到SQL类型的标准映射关系,在向数据库发送时将被转换为相应的SQL类型setNull(int i, int sqlType)将指定参数设置为SQL中的NULL。该方法的第二个

371、参数用来设置参数的SQL类型,具体值从java.sql.Types类中定义的静态常量中选择clearParameters()清除当前所有参数的值课件制作人:XXX11.2.6CallableStatement接口java.sql.CallableStatement接口继承并扩展了PreparedStatement接口,用来执行SQL的存储过程。JDBCAPI定义了一套存储过程SQL转义语法,该语法允许对所有RDBMS通过标准方式调用存储过程。该语法定义了两种形式,分别是包含结果参数和不包含结果参数的形式,如果使用结果参数,则必须将其注册为OUT型参数,参数是根据定义位置按顺序引用的,第一个参数

372、的索引为1。为参数赋值的方法使用从PreparedStatement类中继承来的setXXX()方法。在执行存储过程之前,必须注册所有OUT参数的类型,它们的值是在执行后通过getXxx()方法获得的。CallableStatement接口可以返回一个或多个ResultSet对象。处理多个ResultSet对象的方法是从Statement中继承来的。课件制作人:XXX11.2.7ResultSet接口java.sql.ResultSet接口类似于一个数据表,通过该接口的实例可以获得检索结果集,以及对应数据表的相关信息,例如列名和类型等,ResultSet实例通过执行查询数据库的语句生成。Res

373、ultSet实例具有指向当前数据行的指针,最初,指针指向第一行记录,通过next()方法可以将指针移动到下一行,如果存在下一行该方法则返回true,否则返回false,所以可以通过while循环来迭代ResultSet结果集。默认情况下ResultSet实例不可以更新,只能移动指针,所以只能迭代一次,并且只能按从前向后的顺序。如果需要,可以生成可滚动和可更新的ResultSet实例。课件制作人:XXXResultSet接口ResultSet接口提供了从当前行检索不同类型列值的getXxx()方法,均有两个重载方法,分别根据列的索引编号和列的名称检索列值,其中以列的索引编号较为高效,编号从1开始

374、。对于不同的getXxx()方法,JDBC驱动程序尝试将基础数据转换为与getXxx()方法相应的Java类型并返回。在JDBC2.0API之后,为该接口添加了一组更新方法updateXxx(),均有两个重载方法,分别根据列的索引编号和列的名称指定列。可以用来更新当前行的指定列,也可以用来初始化要插入行的指定列,但是该方法并未将操作同步到数据库,需要执行updateRow()或insertRow()方法完成同步操作。ResultSet接口提供的常用方法如下表所示课件制作人:XXX方 法 名 称功 能 描 述first()移动指针到第一行。如果结果集为空则返回false,否则返回true。如果结

375、果集类型为TYPE_FORWARD_ONLY 将抛出异常last()移动指针到最后一行。如果结果集为空则返回false,否则返回true。如果结果集类型为TYPE_FORWARD_ONLY 将抛出异常previous()移动指针到上一行。如果存在上一行则返回true,否则返回false。如果结果集类型为TYPE_FORWARD_ONLY 将抛出异常next()移动指针到下一行。指针最初位于第一行之前,第一次调用该方法将移动到第一行。如果存在下一行则返回true,否则返回falsebeforeFirst()移动指针到ResultSet实例的开头,即第一行之前。如果结果集类型为TYPE_FORWA

376、RD_ONLY 将抛出异常afterLast()移动指针到ResultSet实例的末尾,即最后一行之后。如果结果集类型为TYPE_FORWARD_ONLY 将抛出异常absolute()移动指针到指定行。有一个int型参数,正数表示从前向后编号,负数表示从后向前编号,编号均从1开始。如果存在指定行则返回true,否则返回false。如果结果集类型为TYPE_FORWARD_ONLY 将抛出异常relative()移动指针到相对于当前行的指定行。有一个int型入口参数,正数表示向后移动,负数表示向前移动,视当前行为0。如果存在指定行则返回true,否则返回false。如果结果集类型为TYPE_F

377、ORWARD_ONLY 将抛出异常getRow()查看当前行的索引编号。索引编号从1开始,如果位于有效记录行上则返回一个int型索引编号,否则返回0findColumn()查看指定列名的索引编号。该方法有一个String型参数,为要查看列的名称,如果包含指定列,则返回int型索引编号,否则将抛出异常isBeforeFirst()查看指针是否位于ResultSet实例的开头,即第一行之前。如果是则返回true,否则返回falseisAfterLast()查看指针是否位于ResultSet实例的末尾,即最后一行之后。如果是则返回true,否则返回falseisFirst()查看指针是否位于Resu

378、ltSet实例的第一行。如果是则返回true,否则返回falseisLast()查看指针是否位于ResultSet实例的最后一行。如果是则返回true,否则返回falseclose()立即释放ResultSet实例占用的数据库和JDBC资源,当关闭所属的Statement实例时也将执行此操作getInt()以int型获取指定列对应SQL类型的值。如果列值为NULL,则返回值0getLong()以long型获取指定列对应SQL类型的值。如果列值为NULL,则返回值0getFloat()以float型获取指定列对应SQL类型的值。如果列值为NULL,则返回值0课件制作人:XXX方 法 名 称功 能

379、 描 述getDouble()以double型获取指定列对应SQL类型的值。如果列值为NULL,则返回值0getString()以String型获取指定列对应SQL类型的值。如果列值为NULL,则返回值nullgetBoolean()以boolean型获取指定列对应SQL类型的值。如果列值为NULL,则返回值falsegetDate()以java.sql.Date型获取指定列对应SQL类型的值。如果列值为NULL,则返回值nullgetObject()以Object型获取指定列对应SQL类型的值。如果列值为NULL,则返回值nullgetMetaData()获取ResultSet实例的相关信息

380、,并返回ResultSetMetaData类型的实例。updateNull()将指定列更改为NULL。用于插入和更新,但并不会同步到数据库,需要执行updateRow()或insertRow()方法完成同步updateInt()更改SQL类型对应int型的指定列。用于插入和更新,但并不会同步到数据库,需要执行updateRow()或insertRow()方法完成同步updateLong()更改SQL类型对应long型的指定列。用于插入和更新,但并不会同步到数据库,需要执行updateRow()或insertRow()方法完成同步updateFloat()更改SQL类型对应float型的指定列。

381、用于插入和更新,但并不会同步到数据库,需要执行updateRow()或insertRow()方法完成同步updateDouble()更改SQL类型对应double型的指定列。用于插入和更新,但并不会同步到数据库,需要执行updateRow()或insertRow()方法完成同步updateString()更改SQL类型对应String型的指定列。用于插入和更新,但并不会同步到数据库,需要执行updateRow()或insertRow()方法完成同步updateBoolean()更改SQL类型对应boolean型的指定列。用于插入和更新,但并不会同步到数据库,需要执行updateRow()或in

382、sertRow()方法完成同步updateDate()更改SQL类型对应Date型的指定列。用于插入和更新,但并不会同步到数据库,需要执行updateRow()或insertRow()方法完成同步updateObject()可更改所有SQL类型的指定列。用于插入和更新,但并不会同步到数据库,需要执行updateRow()或insertRow()方法完成同步moveToInsertRow()移动指针到插入行,并记住当前行的位置。插入行实际上是一个缓冲区,在插入行可以插入记录,此时,仅能调用更新方法和insertRow()方法,通过更新方法为指定列赋值,通过insertRow()方法同步到数据库,

383、在调用insertRow()方法之前,必须为不允许为空的列赋值moveToCurrentRow()移动指针到记住的位置,即调用moveToInsertRow()方法之前所在的行insertRow()将插入行的内容同步到数据库。如果指针不在插入行上,或者有不允许为空的列的值为空,将抛出异常updateRow()将当前行的更新内容同步到数据库。更新当前行的列值后,必须调用该方法,否则不会将更新内容同步到数据库deleteRow()删除当前行。执行该方法后,并不会立即同步到数据库,而是在执行close()方法后才同步到数据库课件制作人:XXX11.3连接数据库在访问数据库时,首先要加载数据库的驱动程

384、序,不过只需在第一次访问数据库时加载一次;然后在每次访问数据库时创建一个Connection实例;紧接着执行操作数据库的SQL语句,并处理返回结果;最后在完成此次操作时销毁前面创建的Connection实例,释放与数据库的连接。课件制作人:XXX11.3.1加载JDBC驱动程序在与数据库建立连接之前,必须先加载欲连接数据库的驱动程序到JVM(Java虚拟机)中,加载方法为通过java.lang.Class类的静态方法forName(StringclassName);成功加载后,会将加载的驱动类注册给DriverManager类;如果加载失败,将抛出ClassNotFoundException异

385、常,即未找到指定的驱动类,所以需要在加载数据库驱动类时捕捉可能抛出的异常。通常情况下将负责加载数据库驱动的代码放在static块中,因为static块的特点是只在其所在类第一次被加载时执行,即第一次访问数据库时执行,这样就可以避免反复加载数据库驱动,减少对资源的浪费,同时提高了访问数据库的速度。【例11-1】课件制作人:XXX11.3.2创建数据库连接java.sql.DriverManager(驱动程序管理器)类是JDBC的管理层,负责建立和管理数据库连接。通过DriverManager类的静态方法getConnection(Stringurl,Stringuser,Stringpasswo

386、rd)可以建立数据库连接,3个参数依次为欲连接数据库的路径、用户名和密码,该方法的返回值类型为java.sql.Connection。【例11-2】课件制作人:XXX11.3.3执行SQL语句建立数据库连接(Connection)的目的是与数据库进行通信,实现方法为执行SQL语句,但是通过Connection实例并不能执行SQL语句,还需要通过Connection实例创建Statement实例,Statement实例又分为3种类型:(1)Statement实例:该类型的实例只能用来执行静态的SQL语句;(2)PreparedStatement实例:该类型的实例增加了执行动态SQL语句的功能;(

387、3)CallableStatement实例:该类型的实例增加了执行数据库存储过程的功能。上面给出三种不同的类型中Statement是最基础的;PreparedStatement继承Statement,并做了相应的扩展;而CallableStatement继承了PreparedStatement,又做了相应的扩展。在11.4节将详细介绍各种类型实例的使用方法。课件制作人:XXX11.3.4获得查询结果通过Statement接口的executeUpdate()或executeQuery()方法,可以执行SQL语句,同时将返回执行结果,如果执行的是executeUpdate()方法,将返回一个int

388、型数值,代表影响数据库记录的条数,即插入、修改或删除记录的条数;如果执行的是executeQuery()方法,将返回一个ResultSet型的结果集,其中不仅包含所有满足查询条件的记录,还包含相应数据表的相关信息,例如每一列的名称、类型和列的数量等。课件制作人:XXX11.3.5关闭连接在建立Connection、Statement和ResultSet实例时,均需占用一定的数据库和JDBC资源,所以每次访问数据库结束后,应该及时销毁这些实例,释放它们占用的所有资源,方法是通过各个实例的close()方法,执行close()方法时建议按照如下的顺序:resultSet.close();state

389、ment.close();connection.close();建议按上面的顺序关闭的原因在于Connection是一个接口,close()方法的实现方式可能多种多样。课件制作人:XXX关闭连接如果是通过DriverManager类的getConnection()方法得到的Connection实例,在调用close()方法关闭Connection实例时会同时关闭Statement实例和ResultSet实例。但是通常情况下需要采用数据库连接池,在调用通过连接池得到的Connection实例的close()方法时,Connection实例可能并没有被释放,而是被放回到了连接池中,又被其他连接调用

390、,在这种情况下如果不手动关闭Statement实例和ResultSet实例,它们在Connection中可能会越来越多,虽然JVM的垃圾回收机制会定时清理缓存,但是如果清理得不及时,当数据库连接达到一定数量时,将严重影响数据库和计算机的运行速度,甚至导致软件或系统瘫痪。课件制作人:XXX11.4操作数据库访问数据库的目的是操作数据库,包括向数据库插入记录或修改、删除数据库中的记录,或者是从数据库中查询符合一定条件的记录,这些操作既可以通过静态的SQL语句实现,也可以通过动态的SQL语句实现,还可以通过存储过程实现,具体采用的实现方式要根据实际情况而定。在增、删、改数据库中的记录时,分为单条操作

391、和批量操作,单条操作又分为一次只操作一条记录和一次只执行一条SQL语句,批量操作又分为通过一条SQL语句(只能是UPDATE和DELETE语句)操作多条记录和一次执行多条SQL语句。课件制作人:XXX11.4.1添加数据在添加记录时,一条INSERT语句只能添加一条记录。如果只需要添加一条记录,通常情况下通过Statement实例完成。【例11-3】【例11-4】【例11-5】【例11-6】【例11-7】课件制作人:XXX11.4.2查询数据在查询数据时,既可以利用Statement实例通过执行静态SELECT语句完成,也可以利用PreparedStatement实例通过执行动态SELECT语

392、句完成,还可以利用CallableStatement实例通过执行存储过程完成。(1)利用Statement实例通过执行静态SELECT语句查询数据的典型代码如下:(2)利用PreparedStatement实例通过执行动态SELECT语句查询数据的典型代码如下:ResultSetrs=statement.executeQuery(select*fromtb_recordwheresex=男);Stringsql=select*fromtb_recordwheresex=?;PreparedStatementprpdStmt=connection.prepareStatement(sql);pr

393、pdStmt.setString(1,男);ResultSetrs=prpdStmt.executeQuery();课件制作人:XXX查询数据(3)利用CallableStatement实例通过执行存储过程查询数据的典型代码如下:无论利用哪个实例查询数据,都需要执行executeQuery()方法,这时才真正执行SELECT语句,从数据库中查询符合条件的记录,该方法将返回一个ResultSet型的结果集,在该结果集中不仅包含所有满足查询条件的记录,还包含相应数据表的相关信息,例如每一列的名称、类型和列的数量等。【例11-8】【例11-9】Stringcall=callpro_record_se

394、lect_by_sex(?);CallableStatementcablStmt=connection.prepareCall(call);cablStmt.setString(1,男);ResultSetrs=cablStmt.executeQuery();课件制作人:XXX11.4.3修改数据在修改数据时,即可以利用Statement实例通过执行静态UPDATE语句完成,也可以利用PreparedStatement实例通过执行动态UPDATE语句完成,还可以利用CallableStatement实例通过执行存储过程完成。(1)利用Statement实例通过执行静态UPDATE语句修改数据的

395、典型代码如下:(2)利用PreparedStatement实例通过执行动态UPDATE语句修改数据的典型代码如下:Stringsql=updatetb_recordsetsalary=3000whereduty=部门经理;statement.executeUpdate(sql);Stringsql=updatetb_recordsetsalary=?whereduty=?;PreparedStatementprpdStmt=connection.prepareStatement(sql);prpdStmt.setInt(1,3000);prpdStmt.setString(2,部门经理);pr

396、pdStmt.executeUpdate();课件制作人:XXX修改数据(3)利用CallableStatement实例通过执行存储过程修改数据的典型代码如下:无论利用哪个实例修改数据,都需要执行executeUpdate()方法,这时才真正执行UPDATE语句,修改数据库中符合条件的记录,该方法将返回一个int型数,为被修改记录的条数。【例11-10】【例11-11】Stringcall=callpro_record_update_salary_by_duty(?,?);CallableStatementcablStmt=connection.prepareCall(call);cablSt

397、mt.setInt(1,3000);cablStmt.setString(2,部门经理);cablStmt.executeUpdate();课件制作人:XXX11.4.4删除数据在删除数据时,既可以利用Statement实例通过执行静态DELETE语句完成,也可以利用PreparedStatement实例通过执行动态DELETE语句完成,还可以利用CallableStatement实例通过执行存储过程完成。(1)利用Statement实例通过执行静态DELETE语句删除数据的典型代码如下:Stringsql=deletefromtb_merchandisewheredate2008-2-14;

398、statement.executeUpdate(sql);课件制作人:XXX删除数据(2)利用PreparedStatement实例通过执行动态DELETE语句删除数据的典型代码如下:注意:当需要为日期型参数赋值时,如果已经存在java.sql.Date型对象,可以通过setDate(intparameterIndex,java.sql.Datedate)方法为日期型参数赋值;如果不存在java、sql、Date型对象,也可以通过setString(intparameterIndex,Stringx)方法为日期型参数赋值。Stringsql=deletefromtb_merchandisewh

399、eredate?;PreparedStatementprpdStmt=connection.prepareStatement(sql);prpdStmt.setString(1,2008-2-14);/为日期型参数赋值prpdStmt.executeUpdate();课件制作人:XXX删除数据(3)利用CallableStatement实例通过执行存储过程删除数据的典型代码如下:无论利用哪个实例删除数据,都需要执行executeUpdate()方法,这时才真正执行DELETE语句,删除数据库中符合条件的记录,该方法将返回一个int型数,为被删除记录的条数。【例11-12】【例11-13】Str

400、ingcall=callpro_merchandise_delete_by_date(?);CallableStatementcablStmt=connection.prepareCall(call);cablStmt.setString(1,2008-2-14);/为日期型参数赋值cablStmt.executeUpdate();课件制作人:XXX11.5应用JDBC事务所谓事务,是指一组相互依赖的操作单元的集合,用来保证对数据库的正确修改,保持数据的完整性,如果一个事务的某个单元操作失败,将取消本次事务的全部操作。例如银行交易、股票交易和网上购物等,都需要利用事务来控制数据的完整性,比如将

401、A账户的资金转入B账户,在A中扣除成功,在B中添加失败,导致数据失去平衡,事务将回滚到原始状态,即A中没少,B中没多。课件制作人:XXX应用JDBC事务数据库事务必须具备以下特征(简称ACID):(1)原子性(Atomic):每个事务是一个不可分割的整体,只有所有的操作单元执行成功,整个事务才成功;否则此次事务就失败,所有执行成功的操作单元必须撤销,数据库回到此次事务之前的状态;(2)一致性(Consistency):在执行一次事务后,关系数据的完整性和业务逻辑的一致性不能被破坏。例如A与B转账结束后,他们的资金总额是不能改变的;课件制作人:XXX应用JDBC事务(3)隔离性(Isolatio

402、n):在并发环境中,一个事务所做的修改必须与其他事务所做的修改相隔离。例如一个事务查看的数据必须是其他并发事务修改之前或修改完毕的数据,不能是修改中的数据;(4)持久性(Durability):事务结束后,对数据的修改是永久保存的,即使系统故障导致重启数据库系统,数据依然是修改后的状态。数据库管理系统采用锁的机制来管理事务。当多个事务同时修改同一数据时,只允许持有锁的事务修改该数据,其他事务只能“排队等待”,直到前一个事务释放其拥有的锁。【例11-14】JSP程序设计教程课件 制作人:XXXJava实用教程第12章JavaWeb程序设计课件制作人:XXX第12章JavaWeb程序设计12.1J

403、SP概述12.2Tomcat安装和启动12.3了解JSP的基本构成12.4JSP的指令标识12.5JSP的脚本标识12.6JSP的动作标识12.7JSP常用内置对象12.8JavaWeb框架技术课件制作人:XXX12.3了解JSP的基本构成在学习JSP语法之前,首先初步了解一下JSP页面的基本结构。请看下面的代码:JSP页面的基本构成今天是:课件制作人:XXX了解JSP的基本构成在上面的代码中,并没有包含JSP中的所有元素,但它仍然构成了一个动态的JSP程序。运行该JSP页面,将显示当前的系统时间。暂且不对其功能实现进行讲解,先来介绍该页面的组成元素。(1)JSP中的指令标识:利用JSP指令可

404、以使服务器按照指令的设置来执行动作和设置在整个JSP页面范围内有效的属性。例如,上述代码中的第一个page指令指定了在该页面中编写JSP脚本使用的语言为Java,并且还指定了页面响应的MIME类型和JSP字符的编码;第二个page指令所实现的功能类似于Java语言中的import语句,用来向当前的JSP文件中导入需要用到的包文件。课件制作人:XXX了解JSP的基本构成(2)HTML标记语言:HTML标记在JSP页面中作为静态的内容,浏览器将会识别这些HTML标识并执行。在JSP程序开发中,这些HTML标记语言主要负责页面的布局、设计和美观,可以说是网页的框架。(3)嵌入的Java代码片段:嵌入

405、到JSP页面中的Java代码,在客户端浏览器中是不可见的。它们需要被服务器执行,然后由服务器将执行结果与HTML标记语言一同发送给客户端进行显示。通过向JSP页面中嵌入Java代码,可以使该页面生成动态的内容。(4)JSP表达式:JSP表达式主要用来数据的输出。它可以向页面输出内容显示给用户,还可以用来动态地指定HTML标记中属性的值。上面介绍的4个元素只是构成JSP页面的一部分,其他的元素如动作标识和JSP注释等都是构成JSP的重要的元素,下面将介绍JSP中的各个元素和它们的语法规则。课件制作人:XXX12.4JSP的指令标识指令标识在客户端不可见,由服务器端解释并执行。常用的指令标识有pa

406、ge和include,这两个指令均以“”标记结束,它们的通用格式如下:下面将分别介绍这两个指令的格式及使用方法。课件制作人:XXX12.4.1使用page指令page指令又称为页面指令,用来为JSP页面定义全局属性,使用格式如下:一个JSP页面可以拥有多个page指令,并且可以放在页面的任意行,但是通常情况下放在页面的最前方,这样可以增强代码的可读性。page指令拥有多个属性,通过设置这些属性可以控制当前的JSP页面。例如,在页面中正确设置当前页面响应的MIME类型为text/html,如果MIME类型设置不正确,则当服务器将数据传输给客户端进行显示时,客户端将无法识别传送来的数据,从而不能正

407、确地显示内容。课件制作人:XXX使用page指令page指令中除import属性外,其他属性最多只能出现一次,page指令可以具有如下属性:language=javacontentType=mimeType;charset=CHARSETimport=package.class|pageage.*,extends=package.classsession=true|falsebuffer=none|8kb|sizekbautoFlush=true|falseisThreadSafe=true|falseinfo=texterrorPage=relativeURLisErrorPage=true

408、|falseisELIgnored=true|falsepageEncoding=CHARSET%课件制作人:XXX使用page指令虽然page指令具有如此多的属性,但是在编程时并不需要一一列出,其中的很多属性可以采用它们的默认值来设置JSP页面。下面将依次讲解page指令中各个属性的功能。课件制作人:XXX使用page指令(1)language属性:设置当前页面中编写JSP脚本使用的语言,默认值为java,例如:上述代码设置了当前页面中使用Java语言来编写JSP脚本,目前只能设置为Java。(2)contentType属性:设置页面响应的MIME类型,通常被设置为text/html,例如:

409、如果类属性设置不正确,如设置为text/css,那么客户端浏览器在显示HTML样式时,不能对HTML标识进行解释,而显示HTML代码。在该属性中还可以设置JSP字符的编码方式,默认编码方式为ISO-8859-1,例如:课件制作人:XXX使用page指令(3)import属性:import属性类似于Java中的import语句,用来向JSP文件中导入需要使用的包。在page指令中可多次使用该属性来导入多个包。例如:或者通过逗号间隔来导入多个包。例如:在JSP中已经默认导入了包java.lang.*、javax.servlet.*、javax.servlet.jsp.*和javax.servlet

410、.http.*,所以,即使没有通过import属性导入,在JSP页面中也可以调用上述包中的类。若要在页面中使用编写的JavaBean,也可通过import属性来导入,还可以通过动作标识来创建一个JavaBean实例进行调用。课件制作人:XXX使用page指令(4)extends属性:extends属性用于指定将一个JSP页面转换为Servlet后继承的类。在JSP中通常不会设置该属性,JSP容器会提供继承的父类。并且如果设置了该属性,可能会影响JSP的编译能力。(5)session属性:该属性的默认值为true,表示当前页面支持session,设为false表示不支持session。(6)bu

411、ffer属性:该属性用来设置out对象(JspWriter类对象)使用的缓冲区的大小。若设置为none,表示不使用缓存,而直接通过PrintWriter对象进行输出;如果将该属性指定为数值,则输出缓冲区的大小不应小于该值,默认值为8KB(因不同的服务器而不同,但大多数情况下都为8KB)。课件制作人:XXX使用page指令(7)autoFlush属性:该属性默认值为true,表示当缓冲区已满时,自动将其中的内容输出到客户端。如果设为false,则当缓冲区中的内容超出其设置的大小时,会产生“JSPBufferoverflow”溢出异常。(8)isThreadSafe属性:该属性默认值为true,表

412、示当前JSP页面被转换为Servlet后,会以多线程的方式来处理来自多个用户的请求;如果设为false,则转换后的Servlet会实现SigleThreadModel接口,该Servlet将以单线程的方式来处理用户请求,即其他请求必须等待直到前一个请求处理结束。(9)info属性:该属性可设置为任意字符串,如当前页面的作者或其他有关的页面信息。可通过Servlet.getServletInfo()方法来获取设置的字符串。例如:访问该页面将显示“Thisisindex.jsp!”。课件制作人:XXX使用page指令(10)errorPage属性:该属性用来指定一个当前页面出现异常时所要调用的页面

413、。如果属性值是以“/”开头的路径,则将在当前应用程序的根目录下查找文件;否则,将在当前页面的目录下查找文件。(11)isErrorPage属性:如果将该属性值设为true,则在当前页面中可以使用exception异常对象。若在其他页面中通过errorPage属性指定了该页面,则当前者出现异常时,会跳转到该页面,并可在该页面中通过exception对象输出错误信息。相反,如果将该属性设置为false,则在当前页面中不能使用exception对象。该属性默认值为false。【例12-1】(12)isELIgnored属性:通过设置该属性,可以使JSP容器忽略表达式语言“$”,其值只能为true或f

414、alse。设为true,则忽略表达式语言。(13)pageEncoding属性:该属性用来设置JSP页面字符的编码。默认值为ISO-8859-1。课件制作人:XXX12.4.2使用include指令该指令用于在当前的JSP页面中使用该指令的位置嵌入其他的文件,如果被包含的文件中有可执行的代码,则显示代码执行后的结果。该指令的使用格式如下:file属性:该属性指定被包含的文件,该属性不支持任何表达式,也不允许通过如下的方式来传递参数。如果该属性值以“/”开头,那么指定的是一个绝对路径,将在当前应用的根目录下查找文件;如果是以文件名或文件夹名开头,那么指定的是一个相对路径,将在当前页面的目录下查找

415、文件。课件制作人:XXX使用include指令使用include指令引用外部文件,可以减少代码的冗余。例如,有两个JSP页面都需要应用下图所示的网页模板进行布局。其中,这两个页面中的LOGO图片区、侧栏和页尾的内容都不会发生变化。如果通过基本JSP语句来编写这两个页面,会导致编写的JSP文件出现大量的冗余代码,不仅降低了开发进程而且会给程序的维护带来很大的困难。课件制作人:XXX使用include指令为了降低代码的冗余,可以将这个复杂的页面分成若干个独立的部分,将相同的部分在单独的JSP文件中进行编写。这样在多个页面中应用上述的页面模板时,就可通过include指令在相应的位置上引入这些文件,

416、而只需对内容显示区进行编码即可。类似的页面代码如下:在这里对内容显示区进行编码课件制作人:XXX12.5JSP的脚本标识在JSP页面中,脚本标识使用得最为频繁,因为它们能够方便、灵活地生成页面中的动态内容,特别是Scriptlet脚本程序。JSP中的脚本标识包括以下3种元素:声明标识(Declaration)、JSP表达式(Expression)和脚本程序(Scriptlet)。通过这些元素,就可以在JSP页面中像编写Java程序一样,来声明变量、定义函数或进行各种表达式的运算。在JSP页面中需要通过特殊的约定来表示这些元素,并且对于客户端这些元素是不可见的,它们由服务器执行。课件制作人:XX

417、X12.5.1JSP表达式(Expression)表达式用于向页面中输出信息,其使用格式为:JSP表达式在页面被转换为Servlet后,成为out.print()方法。所以JSP表达式与JSP页面中嵌入到小脚本程序中的out.print()方法实现的功能相同。如果通过JSP表达式输出一个对象,则该对象的toString()方法会被自动调用,表达式将输出toString()方法返回的内容。课件制作人:XXX12.5.2声明标识(Declaration)在JSP页面中可以声明变量或方法,其声明格式为:特别要注意,在“%”与“!”之间不要有空格。声明的语法与在Java语言中声明变量和方法时是一样的。

418、在页面中通过声明标识声明的变量和方法,在整个页面内都有效,它们将成为JSP页面被转换为Java类后类中的属性和方法。并且它们会被多个线程即多个用户共享。也就是说,其中的任何一个线程对声明的变量或方法的修改都会改变它们原来的状态。它们的生命周期从创建到服务器关闭后结束。下面将通过一个具体实例来介绍声明标识的应用。【例12-2】课件制作人:XXX12.5.3脚本程序(Scriptlet)脚本程序是在JSP页面中使用“”标记起来的一段Java代码。在脚本程序中可以定义变量、调用方法和进行各种表达式运算,且每行语句后面要加入分号。在脚本程序中定义的变量在当前的整个页面内都有效,但不会被其他的线程共享,

419、当前用户对该变量的操作不会影响到其他的用户。当变量所在的页面关闭后就会被销毁。脚本程序使用格式如下:脚本程序的使用比较灵活,它所实现的功能是JSP表达式无法实现的,请看下面的实例。【例12-3】课件制作人:XXX12.6JSP的动作标识在JSP中提供了一系列的使用XML语法写成的动作标识,这些标识可用来实现特殊的功能,例如请求的转发、在当前页中包含其他文件、在页面中创建一个JavaBean实例等。动作标识是在请求处理阶段按照在页面中出现的顺序被执行的,只有它们被执行的时候才会去实现自己所具有的功能。这与指令标识是不同的,因为在JSP页面被执行时首先进入翻译阶段,程序会先查找页面中的指令标识并将

420、它们转换成Servlet,所以这些指令标识会首先被执行,从而设置了整个的JSP页面。课件制作人:XXXJSP的动作标识动作标识通用的使用格式如下:或在JSP中提供的常用的标准动作标识有、和,下面将依次介绍以上各动作标识的使用方法。课件制作人:XXX12.6.1包含文件的动作该动作标识用于向当前的页面中包含其他的文件,这个文件可以是动态文件也可以是静态文件。该标识的使用格式如下:或者向被包含的动态页面中传递参数:page属性:该属性指定了被包含文件的路径,其值可以是一个代表相对路径的表达式。当路径以“/”开头时,则按照当前应用的路径查找这个文件;如果路径是以文件名或文件夹名开头,那么将按照当前的

421、路径来查找被包含的文件。课件制作人:XXX包含文件的动作flush属性:表示当输出缓冲区满时,是否清空缓冲区。该属性值为boolean型,默认值为false,通常情况下设为true。但在JSP1.2以前,flush属性必须设为true。子标识可以向被包含的动态页面中传递参数。标识对包含的动态文件和静态文件的处理方式是不同的。如果被包含的是静态的文件,则页面执行后,在使用了该标识的位置处将会输出这个文件的内容。如果标识包含的是一个动态的文件,那么JSP编译器将编译并执行这个文件。不能通过文件的名称来判断该文件是静态的还是动态的,标识会识别出文件的类型。【例12-4】【例12-5】课件制作人:XX

422、X12.6.2重定向资源的动作动作标识用来将请求转发到另外一个JSP、HTML或相关的资源文件中。当该标识被执行后,当前的页面将不再被执行,而是去执行该标识指定的目标页面。该标识使用的格式如下:如果转发的目标是一个动态文件,还可以向该文件中传递参数,使用格式如下:page属性:该属性指定了目标文件的路径。如果该值以“/”开头,表示在当前应用的根目录下查找文件,否则就在当前路径下查找目标文件。请求被转向到的目标文件必须是内部的资源,即当前应用中的资源。课件制作人:XXX重定向资源的动作如果想通过forward动作转发到应用外部的文件中,例如下面的代码:若当前应用为A,在根目录下的“index.j

423、sp”页面中存在下面的代码用来将请求转发到应用B中的“logon.jsp”页面。那么将出现下面的错误提示:Therequestedresource(/http:/localhost:8080/B/logon.jsp)isnotavailable仔细观察可以看到,错误提示中的路径前自动加入了一个“/”,这是因为index.jsp页面在应用A的根目录下,当forward标识被执行时,会在该目录下查找page属性指定的目标文件,所以会提示资源不存在的信息。课件制作人:XXX重定向资源的动作子标识用来向动态的目标文件中传递参数。这里重点提示一下,标识实现的是请求的转发操作,而不是请求重定向。它们之间的

424、一个区别就是:进行请求转发时,存储在request对象中的信息会被保留并被带到目标页面中;而请求重定向是重新生成一个request请求,然后将该请求重定向到指定的URL,所以事先存储在request对象中的信息都不存在了。课件制作人:XXX12.6.3声明使用JavaBean的动作通过应用动作标识可以在JPS页面中创建一个Bean实例,并且通过属性的设置可以将该实例存储到JSP中的指定范围内。如在指定的范围内已经存在了指定的Bean实例,那么将使用这个实例,而不会重新创建。通过标识创建的Bean实例可以在Scriptlet中应用。该标识的使用格式如下:课件制作人:XXX声明使用JavaBean

425、的动作也可以在标识体内嵌入子标识或其他内容:下面通过下表对标识中各属性的用法作简要说明。属 性说 明id定义一个变量名,程序中将使用该变量名对所创建的Bean实例进行引用type指定了id属性所定义变量的类型scope定位Bean实例的范围,缺省值为page,其他可选值为rquest、session和applicationclass指定一个完整的类名,与beanName属性不能同时存在;若没有设置type属性,那么必须设置class属性beanName指定一个完整的类名,与class属性不能同时存在,设置该属性时必须设置type属性,其属性值可以是一个表示完整类名的表达式课件制作人:XXX声明

426、使用JavaBean的动作下面对表中属性的用法进行详细的介绍。1id属性该属性指定一个变量,在所定义的范围内或Scriptlet中将使用该变量来对所创建的Bean实例进行引用。该变量必须符合Java中变量的命名规则。2type=数据类型type属性用于设置由id属性指定的变量的类型。type属性可以指定要创建实例的类的本身、类的父类或者是一个接口。使用type属性来设置变量类型的使用格式如下。如果在session范围内,已经存在了名为“us”的实例,则将该实例转换为type属性指定的UserInfo类型(必须是合法的类型转换)并赋值给id属性指定的变量;若指定的实例不存在,将抛出beanusn

427、otfoundwithinscope异常。课件制作人:XXX声明使用JavaBean的动作(3)session:说明Bean实例的有效范围为session,可以通过session对象的getAttribute(id属性值)方法获取存储在session中的Bean实例。session是当用户访问Web应用时,服务器为用户创建的一个对象,服务器通过session的ID值来区分其他的用户。针对某一个用户而言,在该范围中的对象可被多个页面共享。(4)application:说明Bean实例的有效范围为从服务器启动开始到服务器关闭结束,可以通过application对象的getAttribute(id属

428、性值)方法获取存储在application中的Bean实例。application对象在启动服务器时被创建,同时被多个用户共享,所以访问该application对象的所有用户共享存储于该对象中的Bean实例。课件制作人:XXX声明使用JavaBean的动作4class=package.classNameclass属性指定了一个完整的类名,其中package表示类包的名字,className表示类的Class文件名称。通过class属性指定的类不能是抽象的,它必须具有公共的、没有参数的构造方法。在没有设置type属性时,必须设置class属性。使用class属性定位一个类的使用格式如下:程序首先

429、会在session范围中来查找是否存在名为“us”的UserInfo类的实例,如果不存在,那么会通过new操作符实例化UserInfo类来获取一个实例,并以“us”为实例名称存储到session范围内。课件制作人:XXX声明使用JavaBean的动作5class=package.classNametype=数据类型class属性与type属性可以指定同一个类,在标识中class属性与type属性一起使用时的格式如下:这里假设UserBase类为UserInfo类的父类。该标识被执行时,程序首先创建了一个以type属性的值为类型,以id属性值为名称的变量us,并赋值为null;然后在sessio

430、n范围内来查找这个名为us的Bean实例,如果存在,则将其转换为type属性指定的UserBase类型(类型转换必须是合法的)并赋值给变量us;如果实例不存在,那么将通过new操作符来实例化一个UserInfo类的实例并赋值给变量us,最后将us变量存储在session范围内。课件制作人:XXX声明使用JavaBean的动作6beanName=package.classNametype=数据类型beanName属性与type属性可以指定同一个类,在标识中beanName属性与type属性一起使用时的格式如下:这里假设UserBase类为UserInfo类的父类。该标识被执行时,程序首先创建了一

431、个以type属性的值为类型,以id属性值为名称的变量us,并赋值为null;然后在session范围内来查找这个名为us的Bean实例,如果存在,则将其转换为type属性指定的UserBase类型(类型转换必须是合法的)并赋值给变量us;如果实例不存在,那么将通过instantiate()方法从UserInfo类中实例化一个类并将其转换成UserBase类型后赋值给变量us,最后将变量us存储在session范围内。课件制作人:XXX声明使用JavaBean的动作如果想在多个页面中共享这个Bean实例,可将scope属性设置为session。在页面中使用标识来实例化一个Bean实例后,可以通过

432、属性来设置或修改该Bean中的属性,或者通过标识来读取该Bean中指定的属性。在本节的开始已经介绍了标识的两种使用格式。(1)不存在Body的格式:(2)在Body内写入内容的格式:/标识开始/标识结束课件制作人:XXX声明使用JavaBean的动作这两种使用方法是有区别的。在页面中应用标识创建一个Bean时,如果该Bean是第一次被实例化,那么对于标识的第二种使用格式,标识体内的内容会被执行,若已经存在了指定的Bean实例,则标识体内的内容就不再被执行了。而对于第一种使用格式,无论在指定的范围内是否已经存在一个指定的Bean实例,标识后面的内容都会被执行。课件制作人:XXX12.6.4设置J

433、avaBean属性值的动作标识通常情况下与标识一起使用,它将调用Bean中的setXxx()方法将请求中的参数赋值给由标识创建的JavaBean中的对应的简单属性或索引属性。该标识的使用格式如下:课件制作人:XXX设置JavaBean属性值的动作下表是对标识中各属性的作简要说明。属 性说 明name必须存在的属性,用来指定一个Bean实例property必须存在的属性,可选值为“*”或指定Bean中的属性。当取值为“*”时,则request请求中的所有参数的值将被一一赋给Bean中与参数具有相同名字的属性;若取值为Bean中的属性,则只会将request请求中与该属性同名的一个参数的值赋给这个

434、Bean属性,若此时指定了param属性,那么请求中参数的名称与Bean属性名可以不同param用于设置请求中的参数,通过该属性指定的参数,其值将被赋给由property属性指定的Bean属性value该属性用来指定一个值,它可以是表示具体值的表达式。通常与property属性一起使用,表示将指定的值赋给指定的Bean属性。value属性不能与param属性一起使用课件制作人:XXX设置JavaBean属性值的动作下面对上表中属性的用法进行详细的介绍。1name属性name属性用来指定一个存在JSP某个范围中的Bean实例。标识将会按照page、request、session和applicat

435、ion的顺序来查找这个Bean实例,直到第一个实例被找到。若任何范围内都不存在这个Bean实例则会抛出异常。2property=*property属性取值为“*”时,则request请求中的所有参数的值将被一一赋给Bean中与参数具有相同名字的属性。如果请求中存在值为空的参数,那么Bean中对应的属性将不会被赋值为null;如果Bean中存在一个属性,但请求中没有与之对应的参数,那么该属性同样不会被赋值为null,在这两种情况下的Bean属性都会保留原来或默认的值。课件制作人:XXX设置JavaBean属性值的动作这种使用方法要求请求中参数的名称和类型必须与Bean中属性的名称和类型一致。但由

436、于通过表单传递的参数都是String类型的,所以JSP会自动将这些参数转换为Bean中对应属性的类型。3property=propertyNameproperty属性取值为Bean中的属性时,则只会将request请求中与该Bean属性同名的一个参数的值赋给这个Bean属性。更进一步讲,如果property属性指定的Bean属性为userName,那么指定Bean中必须存在setUserName()方法,否则会抛出类似于下面的异常:在此基础上,如果请求中没有与userName同名的参数,则该Bean属性会保留原来或默认的值,而不会被赋值为null。与将property属性赋值为“*”一样,当请

437、求中参数的类型与Bean中属性类型不一致时,JSP会自动进行转换。CannotfindanyinformationonpropertyuserNameinabeanoftypecom.Bean.UserInfo课件制作人:XXX设置JavaBean属性值的动作4property=propertyNameparam=parameterNameparam属性指定一个request请求中的参数,property属性指定Bean中的某个属性。这种使用方法允许将请求中的参数赋值给Bean中与该参数不同名的属性。如果param属性指定参数的值为空,那么由property属性指定的Bean属性会保留原来或默

438、认的值而不会被赋为Null。课件制作人:XXX设置JavaBean属性值的动作5property=propertyNamevalue=值其中value属性指定的值可以是一个字符串数值或表示一个具体值的JSP表达式或EL表达式。该值将被赋给property属性指定的Bean属性。当value属性指定的是一个字符串时,如果指定的Bean属性与其类型不一致时,则会将该字符串值自动转换成对应的类型。当value属性指定的是一个表达式时,那么该表达式所表示的值的类型必须与property属性指定的Bean属性一致,否则会抛出argumenttypemismatch异常。通常标识与标识一起使用,但这并不是

439、绝对的,应用如下的方法同样可以将请求中的参数值赋给JavaBean中的属性。【例12-6】课件制作人:XXX12.6.5获取JavaBean属性值的动作标识用来从指定的Bean中读取指定的属性值,并输出到页面中。该Bean必须具有getXxx()方法。标识的使用格式如下:name属性:name属性用来指定一个存在某JSP范围中的Bean实例。标识将会按照page、request、session和application的顺序来查找这个Bean实例,直到第一个实例被找到。若找不到这个Bean实例则会抛出Attemptedabeanoperationonanullobject异常。课件制作人:XXX

440、获取JavaBean属性值的动作property属性:该属性指定的了要获取由name属性指定的Bean中的哪个属性的值。若它指定的值为“userName”,那么Bean中必须存在getUserName()方法,否则会抛出异常:CannotfindanyinformationonpropertyuserNameinabeanoftype此处为类名。如果指定Bean中的属性是一个对象,那么该对象的toString()方法被调用,并输出执行结果。课件制作人:XXX12.7JSP常用内置对象在JSP中提供了9个内置对象,这些对象由容器负责实现和管理,软件开发人员可以直接使用它们,常用的有request

441、、response、session和application。JSP中的9个内置对象的说明,如下表所示。课件制作人:XXX内 置 对 象蕨 类有效范围说 明requestjavax.servlet.http.HttpServletRequestrequest提供对HTTP请求数据的访问,还提供用于加入特定请求数据的上下文responsejavax.servlet.http.HttpServletResponsepage允许直接访问HttpServletReponse对象,可用来向客户端输入数据sessionjavax.servlet.http.HttpSessionsession可用来保存在服务

442、器与一个客户端之间需要保存的数据,当客户端关闭网站的所有网页时,session变量会自动消失applicationjavax.servlet.ServletContextapplicatin代表应用程序上下文,它允许JSP页面与包括在同一应用程序中的任何Web组件共享信息pagejavax.servlet.jsp.HttpJspPagepage代表JSP页面对应的Servlet类实例pageContextjavax.servlet.jsp.PageContextpage代表JSP页面上下文,它提供了唯一一组方法来管理具有不同作用域的属性。这些API在实现JSP自定义标签处理程序时非常有用out

443、javax.servlet.jsp.JspWriterpage提供对输出流的访问configjavax.servlet.ServletConfigpage允许把初始化数据传递给JSP页面exceptionjava.lang.Throwablepage含有只能由指定的JSP“错误处理页面”访问的异常数据课件制作人:XXX12.7.1request对象request对象是从客户端向服务器发出请求,包括用户提交的信息以及客户端的一些信息。客户端可通过HTML表单或在网页地址后面提供参数的方法提交数据,然后通过request对象的相关方法来获取这些数据。request的各种方法主要用来处理客户端浏览器

444、提交的请求中的各项参数和选项。课件制作人:XXXrequest对象1访问请求参数在Web应用程序中,经常需要完成用户与网站的交互。例如,当用户填写表单后,需要把数据提交给服务器处理,服务获取到这些信息并进行处理。request对象的getParameter()方法,可以用来获取用户提交的数据。访问请求参数的方法如下:参数name与HTML标记name属性对应,如果参数值不存在,则返回一个null值,该方法的返回值为String类型。【例12-7】StringuserName=request.getParameter(name);课件制作人:XXXrequest对象2在作用域中管理属性有时,在进

445、行请求转发时,需要把一些数据传到转发后的页面进行处理。这时,就可以使用request对象的setAttribute()方法设置数据在request范围内存取。设置转发数据的方法使用如下:参数key是键,为String类型。在转发后的页面取数据时,就通过这个键来获取数据。参数Object是键值,为Object类型。它代表需要保存在request范围内的数据。获取转发数据的方法如下:参数name表示键名。在页面使用request对象的setAttribute(name,obj)方法,可以把数据obj设定在request范围内。请求转发后的页面使用getAttribute(name);就可以取得数据

446、obj。【例12-8】request.setAttribute(key,Object);request.getAttribute(Stringname);课件制作人:XXXrequest对象3获取CookieCookie是一小段文本信息,伴随着用户请求和页面在Web服务器和浏览器之间传递,为Web应用程序保存用户相关信息。用户每次访问站点时,Web应用程序都可以读取Cookie包含的信息。例如,当用户访问站点时,可以利用Cookie保存用户首选项或其他信息,这样当用户下次再访问站点时,应用程序就可以检索以前保存的信息。在JSP中,可以通过request对象中的getCookies()方法获取C

447、ookie中的数据。获取Cookie的方法如下:request对象的getCookies()方法,返回的是Cookie数组。【例12-9】Cookiecookie=request.getCookies();课件制作人:XXXrequest对象4获取客户信息request对象提供一些用来获取客户信息的方法,如下表所示。【例12-10】方 法说 明getHeader(String name)获得HTTP定义的文件头信息getHeaders(String name)返回指定名字的request Header的所有值,其结果是一个枚举的实例getHeadersNames()返回所有request He

448、ader的名字,其结果是一个枚举的实例getMethod()获得客户端向服务器端传送数据的方法,如get、post、header、trace等getProtocol()获得客户端向服务器端传送数据所依据的协议名称getRequestURI()获得发出请求字符串的客户端地址getRealPath()返回当前请求文件的绝对路径getRemoteAddr()获取客户端的IP地址getRemoteHost()获取客户端的机器名称getServerName()获取服务器的名字getServerPath()获取客户端所请求的脚本文件的文件路径getServerPort()获取服务器的端口号课件制作人:XX

449、Xrequest对象5访问安全信息request对象提供了对安全属性的访问,如下表所示下面的代码使用request对象来确定当前请求是否使用了一个类似HTTP的安全协议。用户安全信息:方 法说 明isSecure()返回布尔值,它用于确定这个请求是否使用了一个安全协议,例如HTTPisRequestedSessionIdFromCookie()返回布尔值,表示会话是否使用了一个Cookie来管理会话IDisRequestedSessionIdFromURL()返回布尔值,表示会话是否使用URL重写来管理会话IDisRequestedSessionIdFromValid()检查请求的会话ID是否

450、合法课件制作人:XXXrequest对象6访问国际化信息浏览器可以通过accept-language的HTTP报头向Web服务器指明它所使用的本地语言。request对象中的getLocale()和getLocales()方法允许JSP开发人员获取这一信息,获取的信息属于java.util.Locale类型。使用这一信息,JSP开发者就可以使用语言所特有的信息作出响应。使用这个报头的代码如下:上面的代码,如果所在区域为中国,将显示“北京欢迎您”,而所在区域为英国,则显示“WelcometoBeiJing”。课件制作人:XXX12.7.2response对象response对象和request对

451、象相对应,用于响应客户请求,向客户端输出信息。response对象是javax.servlet.http.HttpServletResponse接口类的对象,它封装了JSP产生的响应,并发送到客户端以响应客户端的请求。请求的数据可以是各种数据类型,甚至是文件。课件制作人:XXXresponse对象1重定向网页在JSP页面中,可以使用response对象中的sendRedirect()方法将客户请求重定向到一个不同的页面。例如,将客户请求转发到“login_ok.jsp”页面的代码如下:在JSP页面中,还可以使用response对象中的sendError()方法指明一个错误状态。该方法接受一个错

452、误以及一条可选的错误消息,该消息将在内容主体上返回给客户。例如,代码response.sendError(500,请求页面存在错误);将客户请求重定向到一个在内容主体上包含了出错消息的出错页面。response.sendRedirect(login_ok.jsp);课件制作人:XXXresponse对象上述两个方法都会中止当前的请求和响应。如果HTTP响应已经提交给客户,则不会调用这些方法。response对象中用于重定向网页的方法如下所示。【例12-11】方 法说 明sendError(int number)使用指定的状态码向客户发送错误响应sendError(int number,Stri

453、ng msg)使用指定的状态码和描述性消息向客户发送错误响应sendRedirect(String location)使用指定的重定向位置URL想客户发送重定向响应,可以使用相对URL课件制作人:XXXresponse对象2设置HTTP头response对象提供设置HTTP响应报头的方法,如下表所示。【例12-12】方 法说 明setDateHeader(String name,long date)使用名称和日期值设置一个响应报头,如果给定的名称已经设置,则新值会覆盖旧值setHeader(String name,String value)使用名称和值设置一个响应报头,如果给定的名称已经设置,

454、则新值会覆盖旧值setHeader(String name,int value)使用名称和整数值设置一个响应报头,如果给定的名称已经设置,则新值会覆盖旧值addHeader(String name,long date)使用给定的名称和值设置一个响应报头addDateHeader(String name,long date)使用给定的名称和日期值设置了一个响应报头containHeader(String name)返回一个布尔值,它表示是否设置了已命名的响应报头addIntHeader(String name,int value)使用给定的名称和整数值设置了一个响应报头setContentTyp

455、e(String type)为响应设置内容类型,其参数值可以为text/html,text/plain,application/x_msexcel或application/mswordsetContentLength(int len)为响应设置内容长度setLocale(java.util.Locale loc)为响应设置地区信息课件制作人:XXXresponse对象3缓冲区配置缓冲可以更加有效地在服务器与客户之间传输内容。HttpServletResponse对象为支持jspWriter对象而启用了缓冲区配置。response对象提供的配置缓冲区的方法如下表所示。【例12-13】方 法说 明

456、flushBuffer()强制把缓冲区中内容发送给客户getBufferSize()返回响应所使用的实际缓冲区大小,如果没使用缓冲区,则该方法返回0setBufferSize(int size)为响应的主体设置首选的缓冲区大小isCommitted()返回一个boolean,表示响应是否已经提交;提交的响应已经写入状态码和报头reset()清除缓冲区中的数据,同时清除状态码和报头课件制作人:XXX12.7.3session对象HTTP是一种无状态协议。也就是说,当一个客户向服务器发出请求,服务器接收请求并返回响应后,该连接就被关闭了。此时服务器端不保留连接的有关信息,因此当下一次连接时,服务器

457、已没有了以前的连接信息,此时将不能判断这一次连接和以前的连接是否属于同一客户。为了弥补这一缺点,JSP提供了一个session对象,这样服务器和客户端之间的连接就会一直保持下去,但是在一定时间内(系统默认在30分钟内),如果客户端不向服务器发出应答请求,session对象就会自动消失。不过在编写程序时,可以修改这个时间限定值,使session对象在特定时间内保存信息。保存的信息可以是与客户端有关的,也可以是一般信息,这可以根据需要设定相应的内容。课件制作人:XXX12.7.3session对象1创建及获取客户的会话JSP页面可以将对象作为属性来保存。session内置对象使用setAttrib

458、ute()和getAttribute()方法创建及获取客户的会话。setAttribute()方法用于是设置指定名称的属性值,并将其存储在session对象中。setAttribute()方法的语法格式如下:参数name为属性名称,value为属性值。getAttribute()方法用于是获取与指定名字name相联系的属性。getAttribute()方法的语法格式如下:参数name为属性名称。【例12-14】session.setAttribute(Stringname,Stringvalue);session.getAttribute(Stringname);课件制作人:XXXsessio

459、n对象2从会话中移除指定的对象JSP页面可以将任何已经保存的对象进行移除。session内置对象使用removeAttribute()方法将所指定名称的对象移除,也就是说,从这个会话删除与指定名称绑定的对象。removeAttribute()方法的语法格式如下:参数name为session对象的属性名,代表要移除的对象名。【例12-15】session.removeAttribute(Stringname);课件制作人:XXXsession对象3销毁SessionJSP页面可以将已经保存的对象全部删除。session内置对象使用invalidate()方法将会话中的全部内容删除。invalid

460、ate()方法的语法格式如下:session.invalidate();课件制作人:XXXsession对象4会话超时的管理在一个Servlet程序或JSP文件中,确保客户会话终止的唯一方法是用超时设置。这是因为Web客户在进入非活动状态时不以显示的方式通知服务器。为了清除存储在session对象中的客户申请资源,Servlet程序容器设置了一个超时窗口。在非活动的时间超出了窗口的大小时,JSP容器将使session对象无效并撤销所有属性的绑定,从而管理会话的生命周期。session对象用于管理会话生命周期的方法如下表所示。方 法说 明getLastAccessedTime()返回客户端最后一

461、次发送与这个会话相关联的请求时间getMaxInactiveInterval()以秒为单位返回一个会话内两个请求的最大时间间隔,Servlet容器将客户访问期间保存这个会话处于打开状态setMaxInactiveInterval(int interval)以秒为单位指定在服务器小程序容器使该会话无效之前的客户请求之间的最长时间,也就是超时时间课件制作人:XXX12.7.4application对象application对象用于保存所有应用程序中的公有数据,服务器启动并且自动创建application对象后,只要没有关闭服务器,application对象将一直存在,所有用户可以共享applica

462、tion对象。application对象与session对象有所区别,session对象和用户会话相关,不同用户的session是完全不同的对象,而用户的application对象都是相同的一个对象,即共享这个内置的application对象。课件制作人:XXXapplication对象2管理应用程序环境属性在session中设置的属性只是在当前客户的会话范围内容有效,客户超过保存时间不发送请求时,session对象将被回收,而在application对象中设置的属性在整个应用程序范围内是有效的,即使所有的用户都不发送请求,只要不关闭应用服务器,在其中设置的属性仍然是有效的。applicati

463、on对象管理应用程序环境属性的方法如下表所示。【例12-17】方 法说 明removeAttribute(String name)从ServletContext的对象中去掉指定名称的属性setAttribute(String name,Object object)使用指定名称和指定对象在ServletContext的对象中进行关联getAttribute(String name)从ServletContext的对象中获取一个指定对象getAttributeNames()返回存储在ServletContext对象中属性名称的枚举数据THANK YOU FOR YOUR THANK YOU FOR YOUR THANK YOU FOR YOUR THANK YOU FOR YOUR ATTENTIONATTENTIONATTENTIONATTENTION谢谢聆听谢谢聆听

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

最新文档


当前位置:首页 > 医学/心理学 > 基础医学

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