第一章 Java 语言概述

307
Java 第第第第

description

第一章 Java 语言概述. 主要内容提要. Java 语言的发展历史. Java 语言的主要特性. Java 程序相关问题. Java 程序的开发环境. Java 程序的开发过程. Java 语言的发展历史. 1991. 1995. 1998. James Gosling 领导的 Green 小组开发了面向数字家电的 Oak 语言. Internet 迅猛发展 Java 语言正式问世被美国著名杂志 PC Magazine 评为 1995 年十大优秀科技产品之一. - PowerPoint PPT Presentation

Transcript of 第一章 Java 语言概述

Page 1: 第一章  Java 语言概述

第一章 Java语言概述

Page 2: 第一章  Java 语言概述

HUST & IBM Computer Tech. Center

主要内容提要

Java程序的开发环境

Java 程序相关问题

Java语言的主要特性

Java 语言的发展历史

Java 程序的开发过程

Page 3: 第一章  Java 语言概述

HUST & IBM Computer Tech. Center

Java语言的发展历史

Internet迅猛发展 Java语言正式问世被美国著名杂志 PC Magazine评为 1995年十大优秀科技产品之一

James Gosling领导的Green小组开发了面向数字家电的Oak语言

推出了 Java2平台。性能上有所提高,而且对Java的基本模式进行了完善,并提供了更为丰富的 API

1991 1995 1998

Page 4: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java2 的版本划分

Java 2Java 2

J2MEJ2ME

J2SEJ2SE

J2EEJ2EE

Page 5: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java语言的主要特性

平台无关性

简单性

面向对象

分布式、动态性、 可靠性、安全性 ……

多线程

Page 6: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java ——程序相关问题 Java虚拟机

硬件平台

操作系统

J ava程序

Java虚拟机

J ava API

Java虚拟机——在真实机器中用软件模拟实现的一种抽象的机器。( Java 虚拟机规范)

Java虚拟机主要由五个部分组成:指令系 统、寄存器、栈、存储区、碎片回收区

解释和执行 Java程序编译后产生的字节码

Page 7: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java ——程序相关问题 Java API

硬件平台

操作系统

J ava程序

Java虚拟机

J ava API

Java API是 Java系统提供的预先定义好的软件组件的集合,它们提供了许多可供程序员调用的常用功能

丰富的 API 为程序员提供了极大的方便,但也是学习的难点要学会使用 Java API手册 (The Java 2 Platform API Specification )

http://java.sun.com/j2se/1.5/docs/api/index.html

Page 8: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java ——程序相关问题 Java程序的运行机制

操作系统操作系统源代码 可执行代码目标码

编译 连接 运行

源代码 字节码

编译 解释执行

JJavaava解释器解释器

传统语言的运行机制

Java语言的运行机制

Page 9: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java ——程序相关问题 Java程序类型 Java应用程序( Java Application)

是独立完整的程序 在命令行调用独立的解释器软件即可运行 主类必须有 main 方法,这也是程序的入口

Java小程序 Java Applet——是指在客户端运行的 Java小程序,一般来说客户端是指用户所使用的浏览器

Java Servlet——是在服务器端执行的 Java小程序,为了能够支持 Servlet的运行,服务器端必须安装包含 Java虚拟机的服务器软件,这种能够支持服务

端小程序的服务器一般被称为应用服务器

Page 10: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java开发环境JDK/J2SDK( Java Developer Kit)

JDK1.02 JDK1.1.x JDK1.2/J2SDK1.3/J2SDK1.4/JDK5.0(J2SDK1.5)

Java集成开发环境( IDE) NetBeans JBuilder Eclipse JCreator Forte for Java Visual J++ WSAD ……

Page 11: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

JDK的安装与设置

从 http://java.sun.com/可以下载相 关版 本的 JDK(本课程采用 J2SDK1.3以

上版本)在 Windows平台上运行安装程序,以安装JDK

设置 PATH(文件路径)参数。由于 JDK提供的实用程序都在安装目录下的子目录bin下,为了能在任何目录下直接使用文件名调用这些程序,必须设置操作系统的文件路径参数

Page 12: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

环境设置

在Windows环境下,为了快速进入指定目录的命令行窗口,可在注册表中增加项目:

[HKEY_CLASSES_ROOT\Directory\shell\进入命令行 \command]默认值设为:

cmd /k "cd %1"

Page 13: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

JDK的目录结构

bin目录中包含了所有 JDK5.0提供的实用程序demo目录中包含了 JDK5.0自带的实例程序inculde目录中包含了一些支持 Java native方法的 C\C++头文件jre目录中包含了 Java运行环境所需的所有文件,这个目录中所包含的 java运行环境是 JDK私有的,它只为 JDK的实用程序提供支持lib目录中包含了 Java开发环境所需的库文件,它们以 jar文件的形式保存sample目录中包含的是体现JDK5.0 新特性的一些例程

Page 14: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

JDK实用程序简介 javac: Java编译器,将 Java源代码编译为字节码; java: Java解释器,用来解释执行 Java程序的字节码文件;

appletviewer(小程序浏览器 ):一种执行 HTML文件上的 Java小程序类的 Java浏览器;

javadoc:根据 Java源代码及其说明语句生成的 HTML文档;

jdb: Java调试器,可以逐行地执行程序、设置断点和检查变量;

javah:产生可以调用 Java过程的 C过程,或建立能被Java程序调用的 C过程的头文件;

javap: Java反汇编器,显示编译类文件中的可访问功能和数据,同时显示字节代码含义。

Page 15: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java程序的开发过程

编辑源代码

编译源代码文件

运行程序

Page 16: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java ——程序的开发过程 编辑源代码

一般情况下,我们可以使用系统平台下的任何文本编辑器进行源代码的编辑,在 Windows平台下常用的是Window “ ” “ ” 系统自带的 记事本 程序或 写字板 程序

Java源码大小写敏感 Java源码文件的扩展名: .java Java源程序文件也不能随意命名,其文件名必须与程序

中主类的类名完全相同,包括大小写在内

public class MyFirstJavaApp { public static void main(String[] args) { System.out.println(“This is My First Java Application!”); }}

Page 17: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java ——程序的开发过程 编译源代码

使用 JDK实用程序 javac对源代码文件进行编译 C:\MyJava>javac MyFirstJavaApp.java 如果系统提示符再次出现并且没有任何消息产生,那么编译便成功了

如果有系统报错消息产生,则表示程序编译出错,程序员必须阅读报错信息,并根据这些信息对程序进行修改

程序成功编译后,在与源代码文件同一目录下会生成一个新的文件,其文件名与源代码文件名相同,

“扩展名为 .class”。这个文件就是源代码文件编译产生的程序字节码文件 MyFirstJava.class

Page 18: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java ——程序的开发过程 运行程序

要执行一个 Java程序非常简单,只需在字节码文件所在目录下输入下列命令就可以了 : java 字节码文件名

Page 19: 第一章  Java 语言概述
Page 20: 第一章  Java 语言概述

第 2 章 面向对象的编程概念华中科技大学 IBM 技术中心 2006

Page 21: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

主要内容提要

什么是接口

什么是继承

什么是类

什么是消息

什么是对象

Page 22: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

面向对象 vs. 面向过程面向对象( OOP ——) Object-Oriented Programming 用类 class封装数据以及与数据相关的操作 用类的继承性来实现类的重用性 多态性 “ ”面向 对象 ,由对象提供服务

面向过程( POP ——) Procedure-Oriented Programming 以功能为组织单元 通过数据结构来描述具体的问题 数据在功能 (函数 )之间以参数的形式被传送

Page 23: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

现实世界中的对象

现实世界是由对象构成的 现实世界中任何实体都可以看作是对象现实世界中的对象有两个共同特征:

状态 行为

Page 24: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

软件对象(Object)软件对象是现实世界对象的抽象软件对象同样具有状态和行为定义:对象是变量和相关方法的软件组合

变量

方法

Page 25: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

现实对象→软件对象

方法

是否饿了:否

名字:小 Q

颜色:黑

Page 26: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

封装( Encapsulation)封装性体现了面向对象程序设计的一个特性,将方法和数据组织在一起,隐藏其具体实现而对外体现出公共的接口 模块化 隐藏信息 变量

方法

Page 27: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

消息(Message)

复杂的行为必须通过对象之间的交互来实现

软件对象与其它对象进行交互与通讯是通 过互发消息来实现的

对象B

对象 A 消息

Page 28: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

消息的组成

消息的目的对象要执行的方法的名称方法所需参数

你的车 你 换档(低档)

Page 29: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

消息的性质

同一对象可接收不同形式的多个消息,产生不同的响应

同一个消息可以发给不同的对象,所做出的响应可以截然不同

发送方不需要知道接受方如何对请求予以响应的

Page 30: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

类( Class)定义:类是蓝图或原型,它定义了所有某种类的对象的共有的变量和方法

类是具有共同属性和行为的对象的抽象与集合

私有的实现细节

公共 API

Page 31: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

实例( Instance)定义:特定类所描述的一个具体对象

Page 32: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

对象、类与实体的关系

对象

类计算机逻辑的实现

映射计算机世界

实例化 抽象

实体

抽象数据类

现实世界

概念世界

抽象

Page 33: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

继承( Inheritance)广义地说,继承是指能够直接获得已有的性质和特性,而不必重复定义它们。在面向对象的软件技术中,继承是子类自动地共享父类中定义的数据和方法的机制。

共性部分

继承部分

个性部分

父类

子类

Page 34: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

单重继承与多重继承

单重继承:一个子类只有一个唯一确定的父类 单重继承所构成的类的关系结构是一棵树

多重继承:一个子类可以有多个不同的父类 多重继承所构成的类的关系结构是一个格

Java语言仅支持单重继承

Page 35: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

继承的作用

使软件系统具有开放性

更好地进行抽象与分类

实现代码的复用

提高可维护性

Page 36: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

类型( Type)

在面向数值的编程中,类型通常用作数据的表示。在 Java这样的强类型语言中,在编译期,每一个变量和表达式都有一个类型与之相对应

Java中的类型:基本类型、类、接口

Page 37: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

接口( Interface)接口和类一样也是一种类型,也同样包含一些方法的定义。但与类不同的是:接口中所定义的所有方法都是抽象方法(即没有实现的方法)。

接口中所定义的方法由实现( implement)该接口的类来实现,一个类可以同时实现多个接口

接口机制使 Java的面向对象编程变得更加灵活。解决了单重继承带来的问题

接口定义了对象的行为模型,相当于一个协议。实现接口的各个类负责实现接口所定义的行为。虽然实现细节各不相同,但对用户来说是一样的行为。

Page 38: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

面向对象的示例

本例中包含很多对象:点、窗口、颜色、点击事…… 件

代码: ClickMeApp.java , ClickMe.java,Spot.java

Page 39: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Spot类public class Spot { //instance variables private int size; public int x, y; //constructor public Spot() { x = -1; y = -1; size = 1; }

//methods for access to the size instance variable public void setSize(int newSize) { if (newSize >= 0) { size = newSize; } } public int getSize() { return size; }}

Page 40: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Spot对象

private Spot spot = null; ... spot = new Spot();

Page 41: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

示例中的消息

g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, getWidth() - 1, getHeight() - 1);

Page 42: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

示例中的继承和接口

public class ClickMe extends JComponent implements MouseListener { ... }

public class ClickMe extends JComponent implements MouseListener { ... //Methods required by the MouseListener interface. public void mousePressed(MouseEvent event) { if (spot == null) { spot = new Spot(); spot.setSize(RADIUS); } spot.x = event.getX(); spot.y = event.getY(); repaint(); } public void mouseClicked(MouseEvent event) {} public void mouseReleased(MouseEvent event) {} public void mouseEntered(MouseEvent event) {} public void mouseExited(MouseEvent event) {} } }

Page 43: 第一章  Java 语言概述

欢迎提问

Page 44: 第一章  Java 语言概述

第三章 Java语言基础华中科技大学 IBM 技术中心 CodePub.com整理

Page 45: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

变量( Variable)

对象将它的状态存储在变量中定义 :  变量是一个由标识符命名的数据项

变量名必须是一个合法的 标识符 --一个以字母开头的无限制的 Unicode字符序列。

变量的声明: 类型 名称 类型 名称 [ = [ = 初始值初始值 ]]; int i; double pi = 3.1415926; String name;

Page 46: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

数据类型 每个变量都必须有一个数据类型 . 一个变量的数据类型决定了它能容纳的值和在它上面可以进行什么操作。

Java编程语言有两大类数据类型: 原始类型 (primitive) 引用类( reference)

Page 47: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java的数据类型

Java type system

primitive reference

char numeric boolean class interface array

integer floating-point

byte short int long float double

Java type system

primitive reference

char numeric boolean class interface array

integer floating-point

byte short int long float double

Page 48: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

原始类型变量包含单个值,其大小和格式与它的类型匹配:数字、字符或布尔值。

Java语言没有 unsigned类型 0xFFFF和 0xFF谁大?

Java语言必须强制类型转换 float f = 0.1; boolean b = 1;

原始类型

Page 49: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

引用类型

数组,类和接口就是引用数据类型 .与原始类型变量的值不同的是,引用类型变量的值是对应变量代表的一个值或一组值的引用(也就是其地

址)在其他语言里引用被称为指针或者内存地址。 Java不支持显示地使用地址,而是使用变

量的名称代替。

Page 50: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

变量的引用

通过变量名引用变量的值简单名称:由单个标识符组成的名称限定名称:通过类名或对象名引用改类或对象中的成员变量 System.out.println(i+spot.x);

Page 51: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

作用范围

变量的作用范围是可以通过简单名称引用该变量的程序区域

作用范围也决定了系统为该变量创建和释放内存的时间

Page 52: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

例子

int i = 10;if ( i> 0) { int i = 20; System.out.println(“The value of i = ” + i); }System.out.println(“The value of i = ” + i);

Page 53: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

最终变量

你可以在任意范围里将一个变量定义为最终变量( final)

最终变量的值一经初始化就不能改变类似于 C语言中的常量 (const)

final int aFinalVar = 0;

final int blankfinal; . . . blankfinal = 0;

Page 54: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

操作符、表达式、语句和块

自学!

Page 55: 第一章  Java 语言概述

第四章 对象基础和简单数据对象华中科技大学 IBM技术中心

Page 56: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

主要内容

数组

数字

字符和字符串

对象的生存周期

Page 57: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

对象的生命周期

对象的创建 对象的使用 对象的清除对象的创建 对象的使用 对象的清除

Page 58: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

CreateObjectDeompublic class CreateObjectDemo { public static void main(String[] args) { //创建一个 Point对象和两个 Rectangle对象 Point origin_one = new Point(23, 94); Rectangle rect_one = new Rectangle(origin_one, 100, 200); Rectangle rect_two = new Rectangle(50, 100); // 显示 rect_one的宽、高以及面积 System.out.println("Width of rect_one: " + rect_one.width); System.out.println("Height of rect_one: " + rect_one.height); System.out.println("Area of rect_one: " + rect_one.area()); rect_two.origin = origin_one; //设置 rect_two的位置 // 显示 rect_two的位置 System.out.println("X Position of rect_two: " + rect_two.origin.x); System.out.println("Y Position of rect_two: " + rect_two.origin.y); // 移动 rect_two并且显示它的新位置 rect_two.move(40, 72); System.out.println("X Position of rect_two: " + rect_two.origin.x); System.out.println("Y Position of rect_two: " + rect_two.origin.y); }}

Page 59: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

对象的创建

引用变量的声明 实例化对象 对象的初始化引用变量的声明 实例化对象 对象的初始化

类型名 引用变量 = new 构造器 (构造器的参数 )

① ③②

Page 60: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

声明一个变量来引用对象

为了声明一个变量来引用对象,你可以使用类或者接口的名字作为变量的类型

声明并没有创建新对象。在对该引用变量赋值前,该引用为空 ,称为空引用 (null)

类型名 引用变量 = new 构造器 (构造器的参数 )

Point origin_one

Page 61: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

实例化对象

new操作符通过为新对象分配内存来实例化一个类

new操作符需要一个后缀参数,即构造器的一个调用

new操作符返回一个对它所创建对象的引用,通常该引用被赋值给具有适当类型的引用变量 如果 new操作符返回的引用没有被赋给任何变量,那么当 new操作符所在的语句执行完后,将无法访问该对象

类型名 引用变量 = new 构造器 (构造器的参数 )

① ②

Page 62: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

初始化对象

构造器( Constructor):是一个用来创建对象的特殊方法,用来初始化对象的属性。 构造器的名字与类名相同 构造器没有返回值 构造器所包含的语句用来对所创建的对象进行初始化 “ ”没有参数的构造器称为 无参构造器 每个 Java类都至少有一个构造器,如果该类没有显式地声明任何构造器,系统会默认地为该类提供一个不包含任何语句的无参构造器

类型名 引用变量 = new 构造器 (构造器的参数 )

① ③②

Page 63: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

对象创建的实例

public class Point { public int x = 0; public int y = 0; public Point(int x, int y){ this.x = x; this.y = y; } }

Point origin_one = new Point(23, 94);

Page 64: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问 题

Point origin_one = new Point(23, 94);

Point origin_two = new Point(23, 94);

oringin_one==oringin_twoPoint origin_one = new Point(23, 94);

Point origin_two =origin_two;

oringin_one==oringin_two

Page 65: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

构造器的重载(Overload)public class Rectangle { public int width = 0; public int height = 0; public Point origin; public Rectangle() { origin = new Point(0, 0); } public Rectangle(Point p) { origin = p; } public Rectangle(int w, int h) { this(new Point(0, 0), w, h); } public Rectangle(Point p, int w, int h) { origin = p; width = w; height = h; } ……. }

一个类可以包含多个构造器,这种情况成为构造器的重载

同一个类中的多个构造器通过参数的数目及类型的不同来区分

Page 66: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

对象的使用

对象的使用有两种方式 操作或者检查它的变量 调用它的方法

要使用对象的实例成员,首先需要得到该对象的引用 变量

方法

Page 67: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

实例成员与类成员

实例成员包括实例变量与实例方法 实例成员依赖于实例存在 同一个类的不同实例都拥有一份实例变量的拷贝,对某个实例的实例变量的操作不影响到其它实例

实例变量遵循对象的生命周期,随着对象的创建而创建,随着对象的消亡而消亡

必须通过实例的引用来调用实例方法类成员包括类变量与类方法

类成员不依赖于实例存在 同一个类的不同实例共享同一个类变量,对类变量的改变会影响到所有实例

类变量的生存期不依赖于对象,其它类可以不用通过创建该类的实例,直接通过类名访问它们。同样,类方法也可以直接通过类名访问。

Page 68: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

实例成员与类成员

class ABCD { char data; static int share_data;}class Demo { ABCD a,b,c,d; … //实例化}

Page 69: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

实例变量的引用

简单名称 当实例变量处在作用域内 (即对象的类的代码内 ) 的时候

限定名称 objectReference.variableName 当实例变量处在作用域外时使用限定名称

System.out.println("Width of rect_one: " + rect_one.width);System.out.println("Height of rect_one: " + rect_one.height);int height=new Rectangle().height;

Page 70: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

关于变量访问的说明

建议不要通过其它对象或类直接操作对象的变量 ,可能引起无效值

理想情况下 ,类会提供一些方法 ,其他对象可以通过他们检查或修改变量,确保值有效,而且如果变量的类型和名称发生了变化,不会影响它的使用者

在某些情况下,可以允许对对象变量的直接访问,以使类更小更简单,也可使变量适用于更广泛范围;

JAVA编程语言提供了一个访问控制机制,通过这种机制,类可以决定那些其它的类可以直接访问它的变量(第五章中介绍)。

Page 71: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

调用对象的方法

使用限定名称来调用对象的方法objectReference.methodName(argumentList);或者objectReference.methodName();

System.out.println("Area of rect_one: " + rect_one.area());rect_two.move(40, 72);int areaOfRectangle = new Rectangle(100, 50).area();

Page 72: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

关于方法调用

方法被声明为 public,就可以被任何其它的类所访问。有时,类需要限制对它的方法的访问

类可以使用与控制变量访问相同的机制来对它的方法进行访问控制(第五章中介绍)

Page 73: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

对象的清除

JAVA运行时环境在当对象不再被使用的时“候清除它们,这个过程就是所谓的 垃圾收

”集 ( garbage collection)Java的垃圾收集器自动扫描对象的动态内存区,对被引用的对象加标记,然后把没有引用的对象作为垃圾收集起来并释放。

垃圾收集器作为一个线程运行。当系统的内存用尽或程序中调用 System.gc()要求进行垃圾收集时,垃圾收集线程与系统同步运行。否则垃圾收集器在系统空闲时异步地执行。

Page 74: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

无用对象的判定

当某个对象不在被任何引用变量引用时,该对象是无用对象,将被清除。一般有如下两种情况:引用变量超出了作用域{ StringBuffer s = newStringBuffer(“thisisatest”); ……}// 超出对象作用域……

引用变量引用了其它对象或引用了空对象StringBuffer s = new StringBuffer(“test1”); ……s = new StringBuffer(“test2”); // 引用了新的对象 ……s = null; // 引用为空

Page 75: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

finalize()方法

在对对象进行垃圾收集前, Java运行时系统会自动调用对象的 finalize()方法来释放系统资源。

某些情况下,程序员可能需要实现该方法来释放不由垃圾收集器所控制的资源。但这种情况非常少见

finalize()方法是在 Object中有缺省实现,在用户自定义的类中,它可以被覆盖,但一般在最后要调用父类的 finalize()方法来清除对象所使用的所有资源

Page 76: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题一

下列程序的运行结果?

public class SomethingIsWrong { public static void main(String[] args) { Rectangle myRect; myRect.width = 40; myRect.height = 50; System.out.println("myRect's area is " + myRect.area()); }}

Page 77: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题二

现有一个 Point和 Rectangle对象,代码执行后有多少引用指向它们?有没有对象需要垃圾收集?

Point point = new Point(2,4);Rectangle rectangle = new Rectangle(point, 20, 20);point = null;

Page 78: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

字符和字符串

Java API提供了三个处理字符数据的类:

Character:这个类的实例可以容纳单一的字符数值。该类还定义了一些简洁的方法来

操作或者检查单一字符数据。 String:这个类用于处理由多个字符组成的

不可变数据。 StringBuffer:这个类用于存储和操作由多个字符组成的可变数据。

Page 79: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

字符类( Character)

字符类的对象包含单个字符值

当需要使用对象时,可以用字符对象替代原始的 char类型的变量

Page 80: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

——字符类 构造器和方法

Character(char)- Character类唯一的构造器,它创建一个字符对象,其中包含由参数提供的值,一旦创建了Character对象,它包含的值就不能改变。

compareTo(Character)-这个实例方法比较两个字符对象包含的值,这个方法返回一个整数值,表示当前对象中的值是大于、等于还是小于参数所包含的值

Page 81: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

——字符类 构造器和方法

equals(Object)-这个实例方法比较当前对象包含的值与参数对象包含的值,如果两个对象包含的值相等,那么这个方法返回 true

toString()-这个实例方法将此对象转换为字符串

charValue()-这个实例方法以原始char值的形式返回此字符对象包含的值

isUpperCase()-这个实例方法判断一个原始 char值是否是大写字母

Page 82: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

——字符类 例程

public class CharacterDemo { public static void main(String args[]) { Character a = new Character('a'); Character a2 = new Character('a'); Character b = new Character('b'); int difference = a.compareTo(b); if (difference == 0) { System.out.println("a is equal to b."); } else if (difference < 0) { System.out.println("a is less than b."); } else if (difference > 0) { System.out.println("a is greater than b."); } System.out.println("a is "+ ((a.equals(a2)) ? "equal" : "not equal")+ " to a2."); System.out.println("The character " + a.toString() + " is " + (Character.isUpperCase(a.charValue()) ? "upper" : "lower")+ "case."); } }

程序的输出:a is less than b.a is equal to a2.The character a is lowercase.

Page 83: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

——字符类 类方法

Page 84: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题

Character a = new Character('a');Character b = new Character('a');

•下列 boolean表达式的值是 true还是 false?

( 1) a.compareTo(b)==0

( 2) a.equals(b)

( 3) a==b

Page 85: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

字符串和字符串缓冲区

Java平台提供两个类 String和StringBuffer,它们用于存储和操作字符串-由多个字符组成的字符数据。

String类用于其值不能改变的字符串;StringBuffer类用于被修改的字符串,通常用来动态的构造字符数据。

字符串是常量,比字符串缓冲区更高效,而且字符串可以被共享。

Page 86: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

字符串( String)使用字符串常量时,需要创建 String对象,和其它对象不同, String对象可以通过简单赋值语句创建: String name = “Petter”;

此外,也可根据 String类的构造函数创建String对象: String name = new String(“Petter”);

对于程序任何位置出现的双引号标记的字符串,系统都会自动创建一个 String对象。

可通过 String对象的方法对字符串进行操作

Page 87: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

——字符串 构造器

Page 88: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

字符串的不可变性?

String类用于其值不能改变的字符串观察下列程序:

public class StringTest{ public static void main(String[] args){ String s="abc"; s=s+“defg"; System.out.println(s); }}

程序运行结果是 abc还是 abcdefg?

Page 89: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

字符串的不可变性?

abcs

defg

“defg”

s+”defg”

abcdefg

s=s+”defg”

Page 90: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

字符串缓冲区( StringBuffer)

String对象表示的是不可更改的字符串对象,如果需要修改 String对象所表示的内容,必须重新创建一个对象: String str = “Petter”; str = str + “ & Bob” + “ & Tom”;

当修改操作频繁,或字符串的值很大时,会额外分配大量内存

因此, Java语言引入了一个StringBuffer类,用来表示内容可以扩充和修改字符串对象

Page 91: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

StringBuffer——构造器

必须使用 new操作符创建字符串缓冲区

String s = "Dot saw I was Tod";StringBuffer dest = new StringBuffer(s);

Page 92: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

访问器方法

用于获取关于对象的信息的方法被称为访问器方法。

字符串和字符串缓冲区都可以使用的一个访问器方法就是 length方法。

length方法返回字符串和字符串缓冲区中包含的字符数。

String palindrome = "Dot saw I was Tod"; int len = palindrome.length();

Page 93: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

容量

在 StringBuffer类中还有一个capacity()方法,它返回分配给这个字符串缓冲区的容量,而不是使用量。使用量会改变,但是容量始终是不变的。

Page 94: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

通过索引得到字符

charAt()访问器方法,通过索引从字符串或者字符串缓冲区得到字符,索引值从零开始。String anotherPalindrome = "Niagara. O roar again!";

char aChar = anotherPalindrome.charAt(9);

Page 95: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

substring方法

如果要从字符串或者字符串缓冲区得到多个字符,可以使用 substring方法。

String substring(int) String substring(int,int)

String anotherPalindrome = "Niagara. O roar again!";

String roar = anotherPalindrome.substring(11, 15);

Page 96: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

search

string类提供两个访问器方法,返回特定的字符或者子字符串在字符串中的位置。

indexOf()方法从字符串的开头查找;lastindexOf()方法从字符串的末尾查找;

stringBuffer类不支持 indexOf()和lastindexOf()方法。

Page 97: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

search

Page 98: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

search examplepublic class Filename { private String fullPath; private char pathSeparator, extensionSeparator; public Filename(String str, char sep, char ext) { fullPath = str; pathSeparator = sep; extensionSeparator = ext; } public String extension() { int dot = fullPath.lastIndexOf(extensionSeparator); return fullPath.substring(dot + 1); } public String filename() { int dot = fullPath.lastIndexOf(extensionSeparator); int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(sep + 1, dot); } public String path() { int sep = fullPath.lastIndexOf(pathSeparator); return fullPath.substring(0, sep); }}

Page 99: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

search example

public class FilenameDemo { public static void main(String[] args) { Filename myHomePage = new Filename("/home/mem/index.html",'/', '.'); System.out.println("Extension = " + myHomePage.extension()); System.out.println("Filename = " + myHomePage.filename()); System.out.println("Path = " + myHomePage.path()); }}

程序输出:Extension = htmlFilename = indexPath = /home/mem

Page 100: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

比较字符串和字符串缓冲区

Page 101: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

操作字符串

Page 102: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

修改字符串缓冲区

Page 103: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

数字类

Number类及其子类主要用于处理数字Number类的对象包含了原始类型的数值并且提供了一些有用的变量和方法,用于对数值进行处理

Page 104: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

类型包装器类( Type-Wrapper class)

数字类、 Boolean、 Character和void类统称为类型包装器类 在需要对象的地方,可将原始类型的值存储在类型包装器对象中

这些类定义了一些有用的变量,提供关于数据类型的一般信息

这些类还定义了一些有用的方法,用于将值转换为其他类型、转换为字符串等等

这些类用于反射,反射这种 java机制允许程序收集关于 JVM中任何对象或类的信息

此外, BigInteger和 BigDecimal还扩展了原始数据类型

Page 105: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

例程

public class NumberDemo { public static void main(String args[]) { Float floatOne = new Float(14.78f - 13.78f); Float floatTwo = Float.valueOf("1.0"); Double doubleOne = new Double(1.0); int difference = floatOne.compareTo(floatTwo); if (difference == 0) { System.out.println("floatOne is equal to floatTwo."); } else if (difference < 0) { System.out.println("floatOne is less than floatTwo."); } else if (difference > 0) { System.out.println("floatOne is greater than floatTwo."); } System.out.println("floatOne is “ +((floatOne.equals(doubleOne)) ? "equal" : "not equal") + " to doubleOne."); } }

floatOne is equal to oneAgain.

floatOne is not equal to doubleOne.

Page 106: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

数字的转换、格式化、高级算术功能

自学!

Page 107: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

数组

数组是一个固定长度的结构,它存储多个相同类型的值数组直接被 JAVA语言所支持,所以没有一个数组类 数组的长度在数组创建的时候就已经确定。数组元素就是数组中的一个数值,可以通过数组中的位置来访问它。

Page 108: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

创建数组

声明一个引用变量来引用一个数组 格式: type[] 引用变量名

type 引用变量名 [] (允许但不推荐) 数组变量的声明并不创建数组

创建一个数组 使用 new操作符显示地创建数组 格式: new elementType[arraySize]

数组初始化器 可以使用简写的语法创建并初始化数组:

type[] 引用变量名 = { …数组元素值 };

Page 109: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

使用数组

访问数组元素 引用变量名(数组名) [index]

得到数组大小 引用变量名(数组名) .length

Page 110: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

例程

public class ArrayDemo { public static void main(String[] args) { int[] anArray; anArray = new int[10]; for (int i = 0; i < anArray.length; i++) { anArray[i] = i; System.out.print(anArray[i] + " "); } System.out.println(); } }

Page 111: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

对象数组

数组元素可以是基本类型也可以是引用类型当数组元素是引用类型时(也即数组元素为对象时需要注意:数组元素也必须要被创建和初始化

Integer[] anArray = new Integer[5];

for (int i = 0; i < anArray.length; i++){

System.out.println(anArray[i]);

}

Page 112: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

数组的数组

“ ”数组的数组可以看作是 数组引用 的数组与对象数组一样,必须显示地在数组中创建子数组

子数组的长度并不相同 例: int[ ][ ] aMatrix = new int[4][ ];

…… aMatrix[1] = new int[5]; aMatrix[2] = new int[10];

Page 113: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

复制数组

public static void arraycopy(Object source, int srcIndex, Object dest,

int destIndex, int length)

Page 114: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

例程

public class ArrayCopyDemo { public static void main(String[] args) { char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e',

'i', 'n', 'a', 't', 'e', 'd' }; char[] copyTo = new char[7];

System.arraycopy(copyFrom, 2, copyTo, 0, 7); System.out.println(new String(copyTo)); }}

Page 115: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题

public class WhatHappens { public static void main(String[] args) { StringBuffer[] stringBuffers = new StringBuffer[10]; for (int i = 0; i < stringBuffers.length; i ++){ stringBuffers[i].append("StringBuffer at index " + i); } } }

Page 116: 第一章  Java 语言概述

欢迎提问

Page 117: 第一章  Java 语言概述

第六章 接口和包华中科技大学 IBM 技术中心 CodePub.com整理

Page 118: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

主要内容提要

创建和使用包

编写和使用接口

Page 119: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java接口的引入

Java语言只支持单重继承 ,它的程序中的类的层次结构是树状结构 ,在处理复杂问题时单重继承显得力不从心。

为了使 Java程序的类层次结构更加合理,更符合实际问题的需要,我们把用于完成特定功能的若干属性组织成相对独立的属性集合,这种属性的集合就是接口。

Page 120: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java接口定义

定义:接口是一个有名称的方法定义和常量定义的集合 ,但没有方法的实现。

接口定义了一个行为协议 ,类层次结构中任何地方的任何类都可以实现 .

接口是由常量和抽象方法组成的特殊类: 接口中的属性都是用 final修饰的常量 接口中的方法都是用 abstract修饰的没有方法体的抽象方法。

Page 121: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java语言的接口

接口功能的真正实现是由实现接口的各个类来定义接口中各个抽象方法的具体方法体。

Java语言通过接口实现了类间的多重继承功能。

Page 122: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java接口实现多重继承

单一继承指明了子类和父类的层次关系和各自 的行为。多重继承是指一个类有多个父类,这使得类的 层次关系不清楚。 接口则把方法的定义同类的层次区分开来,通 过接口可以在运行中动态地定位所调用的方 法,同时一个类可以实现多个接口,使得接口 提供了比多重继承更简单、更灵活的功能。

Page 123: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

接口 vs 抽象类接口不可以实现任何方法,而抽象类可

以;类可以实现多个接口,但父类仅只有一个;

接口和继承无关 ,不是类层次结构的一部分。无关的类可以实现相同接口。

Page 124: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

定义接口

Page 125: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

完整的接口定义规范

Page 126: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

接口定义

接口包括接口声明和接口体两部分:[public] interface 接口名 [extends 父接口名列表 ] { [public][static][final] 类型 变量名 = 常量值; [public][abstract][native] 返回值类型 方法名 (参数列表 ) [throws 异常列表 ];}public interface MyInterface {

int MAXSIZE = 1024; public abstract myMethod(String name);}

Page 127: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

接口定义的说明

声明接口的关键字 interface引导着所定义的接口名字 (符合 Java标识符规定 );

声明接口也需要给出访问控制符 ;接口具有继承性 ,通过关键字 extends声明该新接口是某父接口的派生接口 ;一个接口可以有多个父接口,它们之间用逗号分隔,形成父接口列表。

Page 128: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

接口体的说明

接口体的定义有两个部分 : 对接口中属性的声明 对接口中方法的声明 ;

系统默认 :接口中的所有属性都是 public ,static和 final (公共,静态和最终 );

系统默认 :接口中的所有方法都是 public 和abstract (公共和抽象 );

接口中方法的方法体可用 Java语言书写 ,也可用其它语言书写 (加 native修饰 )。

Page 129: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

实例

定义一个股票监视器。一旦股票价格变化,立即通知观察者 watcher。

Watcher是一个接口,它只有一个方法, valueChanged知道股票变化的类必须实现此方法。从而必须实现 StockWatcher接口

不仅仅是 StockMointer的超类,其它类只要实现此接口,就可以享受股票价格变化通知服务。

public class StockMonitor { public void watchStock(StockWatcher watcher, String tickerSymbol, double delta) { } }

Page 130: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

实现接口

具体地实现接口所规定的功能 , 需要某个类为接口中的所有抽象方法编写实在的方法体。

在类的声明(定义)中用 implements关键字说明该类将要实现哪些接口 ;

如果实现某个接口的类不是 abstract的抽象类,则在类的定义部分必须为所有抽象方法定义具体方法体,方法头部分应该与接口中的定义完全一致 ;

Page 131: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

实现接口

如果实现某接口的类是 abstract的抽象类 ,则在类的定义部分可以不具体实现接口中的所有方法 ;

一个类在实现某个接口的抽象方法时,必须使用完全相同的方法声明。

接口的抽象方法访问修饰符为 public,所以 ,类在实现方法时必须使用修饰符public,否则,系统将警告 ;因为缩小了接口中定义的方法的访问控制范围。

Page 132: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

实例

public class StockApplet extends Applet implements StockWatcher {

... public void valueChanged(String tickerSymbol, double

newValue) { if (tickerSymbol.equals(sunTicker)) { ... } else if (tickerSymbol.equals(oracleTicker)) { ... } else if (tickerSymbol.equals(ciscoTicker)) { ...}}}

Page 133: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

接口功能不能简单扩大

例如:要加个报股价的方法在接口里,此时所有实现它的类不能正常工作。

public interface StockWatcher { final String sunTicker = "SUNW"; final String oracleTicker = "ORCL"; final String ciscoTicker = "CSCO"; void valueChanged(String tickerSymbol, double newValue); void currentValue(String tickerSymbol, double newValue); }

Page 134: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

用继承来扩大接口

如果需要增加接口的功能,可以利用继承来实现:

public interface StockTracker extends StockWatcher { void currentValue(String tickerSymbol, double newValue); }

Page 135: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题

实现 java.util.Iterator接口的类必须实现哪些方法? Next, hasnext and remove

下面的接口有什么错误?

public interface SomethingIsWrong { public void aMethod(int aValue) { System.out.println("Hi Mom"); }}

Page 136: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题

如何更正上面接口的错误?

下面的接口是正确的吗?

public interface Marker {}

Page 137: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java语言的包 引入的原因:

容易找到和使用类 避免名称冲突 控制访问

定义:包是一个相关的类和接口的集合 ,它可以提供访问保护和名称空间管理。

Page 138: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java语言的包Java平台中的类和接口是各种包的成员,这些类和接口是按照功能绑定的;

例如:基本的类在 java.lang中;再例如:用于输入和输出的类在 java.io中。

Page 139: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java语言的包

包是一种松散的类的集合 ,通常把需要在一起工作的类 (互相访问 )放入一个包。在 Java语言程序设计中,通常需要定

“ ”义许多类;就像利用 文件夹 把许多文件组织在一起,使硬盘管理的文件更清晰、更有条理一样; Java “ ”利用 包 把一些需要在一起操作的类组织在一起,以便程序员更好地管理操作这些类。

Page 140: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

无名包

“ ”系统自动建立 无名包 ,也就是默认包或缺省包

在缺省情况下 ,系统会为每一个 (.java)源文件创建一个无名 (no name)包 ,这个源文件中定义的所有类都隶属于这个无名包 , 它们之间可以相互引用非 private(私有 )的域或方法;

无名包中的类不能被其它包中的类所引用或复用。

Page 141: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

无名包

缺省包一般只用于临时程序或测试程序 .建议在实际系统开发中,为每个类指定有名的

包。Java使用文件系统来存储包,包的名称必须和程序文件所在目录名完全一样(大小写敏感)。

如果定义了一个多级结构的包,其结构也必须 和文件系统的目录结构完全一致。

Page 142: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

有名包

创建有名包的语句格式为 package <包名 >; 语句功能:该语句将创建一个具有指定名字的包,该包将把当前 .java文件中的所有类集合到这个包内。

创建有名包,应该先创建一个子文件夹(同包名 )以便存放当前 .java文件和对应的 .class文件。

Page 143: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

有名包

例如: package cardclasses; 该语句是将当前类置于包 cardclassess中,需要在当前文件夹下创建一个名为cardclasses的子文件夹。再例如: package cardsystem.cardclasses; 该语句将当前类置于cardsystem.cardclasses中,需要在当前文件夹下创建子文件 cardsystem 并在cardsystem下再创建的子文件cardclasses,当前类存放在这个文件夹里。

Page 144: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

使用包成员

只有公共的包成员可以从定义它们的包外访问,要从包外访问公共的包成员,必须采用以下的方法: 用成员的限定名引用; 导入包成员; 导入成员所属的整个包。

Page 145: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

使用包成员

使用包名作为类名前缀 : java.util.Vector vc = new java.util.Vector() 加载需要使用的类 import java.util.Vector; …… Vector vc = new Vector();

Page 146: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

使用包成员

加载整个包 import java.util.*; …… Vector vc = new Vector();消除名称的二义性

使用成员的限定名; 使用环境变量 classpath

set classpath=…… javac –classpath …… MyClass.java java –classpath …… MyClass

Page 147: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

使用包成员

在使用 import语句的时候,可以使用通配符一次导入一个包中的所有类,如:

import java.util.*;这样,我们在使用 java.util包中的任何类时,就可以直接使用简单类名。需要注意的是, import语句要么导入一个类,要么导入一个完整包。不能使用通配符标记包的子集或多个包,下面三条语句均无法通过编译:

import java.applet.A*; import java.*.*; import java.*.io;

Page 148: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

使用包成员

为了简化代码, Java语言规定在以下情况时无需使用 import语句导入包: 使用缺省包中的类 使用 java.lang包中的类 使用和当前类在同一个包中的其他类

Page 149: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

管理源代码文件

将类或者接口的源代码放在一个文本文件中,文件名为类或者接口的简单名;

将源代码文件放在一个目录中,目录名反映的是类或者接口所属的包的名称。

例如:

Page 150: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

管理源代码文件

包成员的限定名称与文件的路径是对应的,它们的对应关系为:

Page 151: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

管理类文件

与源代码文件一样,字节码文件也可以通过包来进行管理;

字节码文件不必和源代码文件位与相同的目录中,可以单独管理;这样做的目的可以隐藏源代码文件。

Page 152: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

类路径

定义:类路径是一个目录或 zip文件的有序列表,用于搜索类文件。

类路径中列出的每个目录都是包含包目录的顶层目录,编译器和解释器可以根据类的包名称和类名从顶层目录开始构造路径的其余部分。

例如:上图所示的目录结构的类路径项目包含 classes,但是不包含 com或者 com以下的任何目录,编译器和解释器用 .class文件的完整包名构造它的路径名。

Page 153: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题

假设你已经写了一些类,并且需要将这些类放进三个包中,如下所示:

为了将这些类放到正确的包中,需要在每个源代码中增加什么代码?

Page 154: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题

In Client.java add: package mygame.client;

In Server.java add: package mygame.server;:

In Utilities.java add: package mygame.shared;

Page 155: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题

“ ”为了遵守 管理源代码文件和类文件 所述的目录结构,需要在开发目录下创建一些子目录,并且将源代码文件放到正确的子目录中,必须创建哪些子目录?各个源代码文件应该放在哪个子目录中?

In mygame/client/ place: Client.java In mygame/server/ place: Server.java In mygame/shared/ place: Utilities.java

Page 156: 第一章  Java 语言概述

欢迎提问

Page 157: 第一章  Java 语言概述

第 7 章 异常处理华中科技大学 IBM技术中心

Page 158: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

为什么要异常处理?

对于任何语言的程序设计而言,错误的发生总是不可避免的

为了加强程序的健壮性,程序设计时,必须充分考虑错误发生的可能性,并建立相应的处理机制。

Page 159: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

什么是异常?

异常( Exception)又称为例外,是指在程序运行过程中发生的非正常事件,这些事件的发生会影响程序的正常执行。如: “ ”进行数学中 无意义 的运算,例如除数为零、对负数求对数平方根等

对数组进行操作时,超出了数组的最大下标 程序所需进行的 I/O操作不能正常执行,如所需访问的文件不存在

内存耗尽无法进行类的实例化 JVM崩溃

Page 160: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

异常对象

在 Java语言中,我们用异常对象来表示不同的异常。

所谓 Java异常对象就是一个存放着相关错误信息的对象,如果方法运行时产生了异常,该方法就可以抛出一个异常对象

为了表示不同种类的异常, Java语言中定义了许多异常类。

Page 161: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

方法的调用堆栈

main()

methodA()

methodB()

methodC() 调用

Java程序在执行的过程中,形成了一个先进后出的调用堆栈,各方法之间依照调用先后的不同,由先至后的进入调用堆栈,堆栈的最上层即是当前被调用执行的方法。该方法执行完毕后,会将

处理器控制权交还给调用他的方法,依此类推。

Page 162: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

方法调用堆栈中异常对象的传递

当某一方法中的一个语句抛出一个异常时,如果该方法中没有处理该异常的语句,那么该方法就会中止执行,并将这个异常传递给堆栈中的下一层方法,直到某一方法中含有处理该异常的语句为止。如果该异常被传递至主方法,而主方法中仍然没有处理该异常的语句,则异常将会被抛至 JVM,程序中断。

main()

methodA()

methodB()

methodC() 调用

Page 163: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

例 程public class ExampleOfException { String[] lines = {"The first line", "The second line","The last line"}; public static void main (String[] args) { ExampleOfException eoe = new ExampleOfException(); eoe.methodA(); System.out.println("Program finished."); } void methodA() { methodB(); } void methodB() { methodC(); } void methodC() { for (int i=0; i<4; i++) System.out.println (lines[i]); }}

The first lineThe second lineThe last lineException in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at ExampleOfException.methodC(ExampleOfException.java:16) at ExampleOfException.methodB(ExampleOfException.java:12) at ExampleOfException.methodA(ExampleOfException.java:9) at ExampleOfException.main(ExampleOfException.java:6)

Page 164: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java中的异常类

在 Java语言中,任何的异常对象都是 Throwable类的直接子类或间接子类的实例。 Java的类库已经提供了一些常见的异常类,如果这些异常类不能够

满足要求,用户也可以创建自己的异常类。

Throwable

Exception

RuntimeException IOException

NullPointerException ArithmeticException …… FileNotFoundException

……

……

Error

VirtualMachineError ……

Page 165: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Exception类

Exception的子类表示了不同类型的异常,例如 RuntimeException表示运行时异常,而 IOException表示 I/O问题引起的异常。

这些子类也可以被继承以对不同类型的异常进行细分,如 RuntimeException还可细分为NullPointerException、 ArithmeticException等; IOException还可细分为FileNotFoundException、 EOFException等。

Page 166: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

常见的异常类

ArithmeticExceptionArrayIndexOutOfBandsExceptionIOExceptionFileNotFoundExceptionNullPointerExceptionNumberFormatException

Page 167: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Error类

Error类表示 Java运行时产生的系统内部错误或资源耗尽等严重错误。

这种错误通常是程序无法控制和解决的,如果发生这种错误,通常的做法是通知用户并中止程序的执行。

Page 168: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

常见的错误类

NoClassDefFoundErrorOutOfMemoryErrorVirtualMachineError

Page 169: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

必检异常与非必检异常

RuntimeException类及其子类被称“ ”为 运行时异常

一般发生在 JRE内部 “ ”也称 非必检异常 如 NullPointerException

“ ”其他异常被成为 非运行时异常 一般发生在 JRE外部 “ ”也称 必检异常 如 IOException

Page 170: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

异常处理的一般步骤

异常抛出

异常捕获

异常处理

Page 171: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

抛出异常

方法中需要抛出异常时,可使用 throw语句实现,具体步骤应该是: 选择合适的异常类; 创建该类的一个对象; 使用 throw语句抛出该对象。

Page 172: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

抛出异常

例如,某方法 readFile()对文件进行读操作,根据前面章节的介绍可以知道:当进行 I/O操作时,可能会产生 I/O异常。所以,在方法readFile中如果读文件操作不成功,则应抛出I/O异常。如下列程序片断所示:

readFile() throws IOException{ … if (读文件不成功 )

throw new IOExcepion();}

Page 173: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

抛出异常

如果一个方法可能抛出多个必检异常,那么必须在方法的声明部分一一列出,多个异常间使用逗号进行分隔:

Class MyClass {…

public myMethod(String s) throws IOException, MalformedURLException { … } …}

Page 174: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

抛出异常

一个方法必须通过 throws语句在方法的声明部分说明它可能抛出而并未捕获的所

“ ”有的 必检异常 ,如果没有这么做,将不能通过编译。

值得注意的是:如果在子类中覆盖了父类的某一方法,那么该子类方法不可以比被其覆盖的父类方法抛出更多的异常(但可以更少)。所以,如果被覆盖父类的方法

“ ”没有抛出任何的 必检异常 ,那么子类方“ ”法绝不可能抛出 必检异常 。

Page 175: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

抛出异常

在下面的例子里,对于父类 SuperClass而言,类 SubClassA是正确的子类,而SubClassB 则是错误的。

class SuperClass{public superMethod() throws EOFException {

…}

}class SubClassA extends SuperClass{ //正确

public superMethod() {…

}}class SubClassB extends SuperClass{ //错误

public superMethod() throws FileNotFoundException{…

}}

Page 176: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

异常的捕获

要捕获一个异常,程序员只需要在程序中设置一个 try/catch块,其格式如下:

try{ 抛出异常的代码 }catch (某 Exception 类型 e){ 处理该异常类型的代码 }catch (某 Exception 类型 e){ 处理该异常类型的代码 }

Page 177: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

异常的捕获

当 try块中的某条代码抛出异常时:首先,自该语句的下一条语句起的所有 try块中的剩余语句将被跳过不予执行;其次,程序执行 catch子句进行异常捕获,异常捕获的目的是进行异常类型的匹配,并执行与所抛出的异常类型相对应的catch子句中的异常处理代码。

Page 178: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

异常的捕获

需要注意的是:如果 try块中没有任何的异常抛出,则所有的 catch子句将会被跳过;如果 try块中所抛出的异常对象类型与所有的 catch子句中的所声明的异常类型都不匹配,则方法会立即中止,并将该异常对象继续抛出,沿调用堆栈传递。

Page 179: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

example

public class ExampleOfException { String[] lines = {"The first line", "The second line","The last line"}; public static void main (String[] args) { ExampleOfException eoe = new ExampleOfException(); eoe.methodA(); System.out.println("Program finished."); } ... void methodC() { for (int i=0; i<4; i++) { try { System.out.println (lines[i]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Re-setting Index Value"); } } }}

Page 180: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

example上面的例子中可能会产生数组越界异常,所以将其置于 try块中,并在 catch子句中对ArrayIndexOutOfBoundsException类型的异常进行捕获,并进行处理。

如果 try块中可能抛出多个类型的异常,程序员可以使用多个 catch子句对这些异常进行捕获,每种异常类型对应一个单独的 catch子句。

需要注意的是,这些 catch子句是顺序执行的。这意味着,异常对象总是被第一个 catch子句首先捕获,如果类型不匹配,才会执行下一个catch子句。读者可以试着分析下面的程序片断,看看有什么样的问题存在。

Page 181: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题

Java运行系统从上到下分别对每个 catch语句处理的例外类型进行检测 ,直到类型匹配为止;

catch语句的排列顺序应该是从子类到父类

try { …}catch(Exception e) { … }catch(IOException e) { … }catch(ArrayIndexOutOfBoundsException e) { … }

Page 182: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

finally

当一个方法的某条语句抛出异常后,该方法剩余的语句将无法继续执行。这种情况下,方法往往无法将其占用的资源进行释放。

解决方法: 在每个 catch子句的异常处理代码中也加上资源释放的代码,但这种方法非常麻烦;

Java语言的异常处理机制中提供了一个更好的方案-程序员可以使用 finally子句来统

一进行资源释放之类的工作。

Page 183: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

finally

finally子句的一般格式: try{

抛出异常的代码 }catch (某 Exception 类型 e){

处理该异常类型的代码 }

… }catch (某 Exception 类型 e){

处理该异常类型的代码 }finally{

最后一定会被执行的代码 }

Page 184: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

finally

不论 try块中的代码是否抛出异常及异常是否被捕获, finally子句中的代码一定会被执行: 如果 try块中没有抛出任何异常,当 try块中的代码执行结束后, finally中的代码将会被执行;

如果 try块中抛出了一个异常且该异常被 catch正常捕获,那么 try块中自抛出异常的代码之后的所有代码将会被跳过,程序接着执行与抛出异常类型匹配的catch子句中的代码,最后执行 finally子句中的代码。

如果 try块中抛出了一个不能被任何 catch子句捕获(匹配)的异常, try块中剩下的代码将会被跳过,程序接着执行 finally子句中的代码,未被捕获的异常对象继续抛出,沿调用堆栈顺序传递。

Page 185: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题

当调用上述方法 m()时, try块中包含方法的 return语句,返回值为 1。然而,实际调用该方法后产生的返回值为 0。这是因为在方法实际返回并结束前, finally子句中的内容无论如何要被执行,所以 finally子句中的 return语句使得该方法最终实际返回值为 0 。

public int m(){ try {

return 1; }finally{

return 0; }}

Page 186: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

example

public class TryCatchFinally{ static void Proc( int sel ){ System.out.println("----- In Situation"+sel+" -----"); try{ if( sel==0 ){ System.out.println("no Exception caught"); return; }else if( sel==1 ){ int i=0; int j=4/i; }else if( sel==2 ){ int iArray[]=new int[4]; iArray[10]=3; }

Page 187: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

example

}catch( ArithmeticException e ){ System.out.println("Catch "+e); }catch( ArrayIndexOutOfBoundsException e ){ System.out.println("Catch "+e.getMessage()); }catch( Exception e ){ System.out.println("Will not be executed"); }finally{ System.out.println("in Proc finally"); } } public static void main( String args[] ){ Proc( 0 ); Proc( 1 ); Proc( 2 ); }}

程序运行结果:----- In Situation0 -----no Exception caughtin Proc finally----- In Situation1 -----Catch java.lang.ArithmeticException: / by zeroin Proc finally----- In Situation2 -----Catch 10in Proc finally

Page 188: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

声明异常

一个方法不处理它产生的异常 ,而是沿着调用堆栈向上传递 ,由调用它的方法来处理这些异常,则需要声明异常。

声明异常的方法: returnType methodName([paramlist]) throws

exceptionList例如: void compute(int x) throws

ArithmeticException{ … }

Page 189: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

example

public class ThrowsException1{ static void Proc(int sel) throws ArrayIndexOutOfBoundsException { System.out.println("-----In Situation"+sel+"-----"); if(sel==0){ System.out.println("no Exception caught"); return; }else if(sel==1){ int iArray[]=new int[4]; iArray[10]=3; } }

Page 190: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

example

public static void main(String args[]){ try{ Proc(0); Proc(1); }catch(ArrayIndexOutOfBoundsException e){ System.out.println("Catch "+e); }finally{ System.out.println("in Proc finally"); } }} 程序运行结果:

----- In Situation0 -----no Exception caught----- In Situation1 -----Catch java.lang.ArrayIndexOutOfBoundsException: 10in Proc finally

Page 191: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

创建自己的异常类

Java语言中允许用户定义自己的异常类,这些用户自定义异常类必须是 Throwable的直接子类或间接子类。

根据 Java异常类的继承关系,用户最好将自己的异常类定义为 Exception的子类,而不要将其定义为 RuntimeException的子类。因为对于 RuntimeException的子类而言,即使调用者不进行处理,编译程序也不会报错。将自定义异常类定义为Exception的子类,可以确保调用者对其进行处理。

Page 192: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

example

class MyException extends Exception{ private int detail; MyException( int a ){ detail = a; } public String toString( ){ return "MyException "+detail; }}

Page 193: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

example

public class ExceptionDemo{ static void compute(int a) throws MyException { System.out.println("called compute("+a+")"); if( a>10 ) throw new MyException(a); System.out.println("normal exit"); } public static void main( String args[] ){ try{ compute( 1 ); compute( 20 ); } catch( MyException e ){ System.out.println("Caught "+e); } }}

程序运行结果:called compute(1)normal exitcalled compute(20)Caught MyException 20

Page 194: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

异常的优点

“ ”将错误处理代码与 常规 代码分离; 例 7.7.1

将错误沿调用堆栈传递; 可以由感兴趣的方法来处理异常

对错误类型进行分组和区分。

Page 195: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

说明的问题

方法也可以不对异常进行捕获而直接将其抛出,并在方法声明中进行说明,那么对方法产生的异常到底是应该直接进行捕获还是应该将其进行传递呢?

一般来说,对于方法的最终调用者而言,他必须捕获并处理该方法抛出的异常。而对于抛出异常的方法而言,应该对方法可能产生的异常进行区分,尽量避免一些异常的产生,捕获并处理那些你知道如何处理的异常,而对那些你不知道方法的调用者会如何处理的异常,最好将它们留给方法的调用者进行处理,这样会增加程序的灵活性。

Page 196: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

说明的问题

需要特别指出的是,虽然异常处理机制为程序员提供了非常大的方便,但是作为一个好的程序员要尽量避免异常的过度使用。这是因为:异常对象的实例化和其后续处理工作是非常消耗资源的,过度的使用异常会明显影响程序的执行速度。所以,在使用异常处理时应该仔细考虑,只对有必要的异常情况使用异常,而不可以

将异常泛化。

Page 197: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

两段代码的比较

代码 1:try { int n = InputReader.inputInteger(请输入一个整数 "); if (n<100 || n>1) throw new NumberFormatException();}catch (NumberFormatException e) {

System.out.println("输入范围错误! ");}

代码 2:int n = InputReader.inputInteger(请输入一个整数 ");if (n<100 || n>1)

System.out.println("输入范围错误! ");

代码 1采用了异常处理方式;代码 2则通过对用户输入的分析避免了异常的使用,提高了代码效率。

Page 198: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题

下面的代码合法吗?try {...} finally {...}

下面的代码可以捕获何种异常?使用这种异常处理器有什么问题?catch (Exception e) {...}

Page 199: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题

下面的处理器可以捕获什么异常?} catch (Exception e) {...} catch (ArithmeticException a) {...}这个异常处理器中有错误吗?此代码能否被编译?

Page 200: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

问题public static void cat(File named) { RandomAccessFile input = null; String line = null; try { input = new RandomAccessFile(named, “r”); while ((line = input.readLine()) != null { System.out.println(line); } return; } finally { if (input != null) { input.close(); } }}

Page 201: 第一章  Java 语言概述

第八章 线程华中科技大学 IBM技术中心

Page 202: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

主要内容

线程的死锁

线程的同步

线程的生存周期

如何创建线程

线程的基本概念

Page 203: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

什么是线程

线程是程序内的一个单一的顺序控制流“程,也被称为 轻型进程 (lightweight

process)” “或 执行上下文 (execution context )”

线程用于分隔任务线程类似于传统的顺序程序,都有一个执行的起点,经过一系列指令后到达终点。线程在执行过程中的任何时刻只能有一个执行点

Page 204: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

几个相关概念

1

“ ”程序 代表一个静态的对象,是内含指令和数据的文件,存储在磁盘或

其他存储设备中

2

“ ”进程 代表一个动态的对象,是程序的一个执行过程,存在于系统的内存中。一个进程对应于一个程序

3

“ ”线程 是运行于某个进程中,用于完成某个具体任务的顺序控制流程,有时被称为轻型进程。

Page 205: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

线程的作用

线程真正的神奇之处并不在于它处理顺序任务流程的作用,而是在于多个线程可以同时运行,并且在一个程序内执行不同的任务

演示排序程序

Page 206: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

如何创建线程

继承 Thread类

定义线程的方法

实现 Runnable接口

Page 207: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

继承 Thread类

在构造函数中调用父类的构造函数 参考 Thread类的构造函数

在 run方法中实现任务处理功能创建线程对象后,通过调用 start()方法启动线程

Page 208: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

继承 Thread类 class PrintThread extends Thread { private int sleepTime; public PrintThread( String name ) { super( name ); sleepTime = (int) ( Math.random() * 5000 ); System.out.println( "Name: " + getName() + "; sleep: " + sleepTime ); } public void run() { try { System.out.println( getName() + " going to sleep" ); Thread.sleep( sleepTime ); } catch ( InterruptedException ie ) { System.err.println( ie.toString() ); } System.out.println( getName() + " done sleeping" ); } }

Page 209: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

执行线程任务

public class ThreadTester { public static void main( String args[] ) { PrintThread thread1, thread2, thread3, thread4; thread1 = new PrintThread( "thread1" ); thread2 = new PrintThread( "thread2" ); thread3 = new PrintThread( "thread3" ); thread4 = new PrintThread( "thread4" ); System.out.println( "\nStarting threads" ); thread1.start(); thread2.start(); thread3.start(); thread4.start(); System.out.println( "Threads started\n" ); } }

Page 210: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

实现 Runnable接口

实现 run方法,在该方法中实现任务处理功能 参考 Runnable接口定义

创建实现 Runnable接口的类对象利用 Thread类的构造函数创建线程对象

public Thread(Runnable target) 通过调用线程对象的 start()方法启动线程

Page 211: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

实现 Runnable接口 class PrintRunnable implements Runnable { private int name; private int sleepTime; public PrintRunnable( String name ) { this.name = name; sleepTime = (int) ( Math.random() * 5000 ); System.out.println( "Name: " + name + "; sleep: " + sleepTime ); } public void run() { try { System.out.println( name + " going to sleep" ); Thread.sleep( sleepTime ); } catch ( InterruptedException ie ) { System.err.println( ie.toString() ); } System.out.println( name + " done sleeping" ); } }

Page 212: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

执行线程任务

public class RunnableTester { public static void main( String args[] ) { PrintRunnable thread1, thread2, thread3, thread4; thread1 = new PrintRunnable ( "thread1" ); thread2 = new PrintRunnable ( "thread2" ); thread3 = new PrintRunnable ( "thread3" ); thread4 = new PrintRunnable ( "thread4" ); System.out.println( "\nStarting threads" ); new Thread(thread1).start(); new Thread(thread2).start(); new Thread(thread3).start(); new Thread(thread4).start(); System.out.println( "Threads started\n" ); } }

Page 213: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

选择合适的方式创建线程

继承 Thread类 简单直观 不能继承其他父类

实现 Runnable接口 可继承其他父类 代码稍复杂

ClockApplet示例

Page 214: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

ClockApplet示例

import java.applet.Applet; import java.awt.Graphics; import java.util.Date; public class ClockApplet extends Applet implements Runnable { private Thread clockThread = null; public void start() { if (clockThread ==null) { clockThread = new Thread(this); clockThread.start(); } } public void paint(Graphics g) { Date date = new Date(); g.drawString(date.toString(), 5, 10); }

Page 215: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

ClockApplet示例

public void run() { while (true) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e) { } } }}

Page 216: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

线程的生存周期

创建 消亡运行

阻塞

就绪

休眠

等待

start()

sleep()

wait()

I/O

CPU可用 任务完成

yield()

Page 217: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

线程状态的转换条件

可运行状态和不可运行状态转换条件

进入不可运行状态条件 返回可运行状态条件挂起(调用 suspend()方法) 调用 resume()方法

睡眠(调用 sleep()方法) sleep()方法的指定时间结束

阻塞(请求 I/O操作) I/O操作结束

等待(调用某对象的 wait()方法) 调用该对象的 notfiy()或 notifyAll()方法

Page 218: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

停止线程

正常终止 run()方法运行完毕

强行中止 调用线程对象的 stop()方法 创建线程对象的上级线程停止

Page 219: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

线程的优先级

Java线程优先级 范围从 1- 10,数字越高越能被优先执行 通过线程对象的 setPriority()方法设置优先级 缺省优先级为 5 三个常数:

MAX_PRIORITY、MIN_PRIORITY、 NORM_PRIORITY

Page 220: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

线程的调度

大多数计算机只有一个 CPU,因此一个时刻只“有一个线程在运行,多个线程只能是 宏观上并

”行,微观上串行在有限个 CPU的系统中确定多个线程的执行顺序称为线程的调度

Java “语言采用了简单的 固定优先级调度算”法 ,高优先级的线程总是更容易得到 CPU使用权。

只有当所有高优先级的线程停止或处于不可运行状态,低优先级的线程才能运行。

Page 221: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

抢占式调度

Java “ ”语言的 抢占式调度策略 当一个线程正在运行时,如果有更高优先级的线程处

“ ”于 可运行 状态,系统将强制暂停低优先级的线程,“ ”使高优先级的线程 抢占 低优先级线程的 CPU资源

Page 222: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

自私的线程

线程如果不放弃 CPU,其他同优先级的线程就很难得到运行

run() {while(true) {……// yield();}

}除非更高优先级的抢占 CPU ……,或者

Page 223: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

时间片策略

部分平台(如Windows “ ”)针对 自私线程 采用 了时间片轮换策略

将 CPU的运行时间划分成段,相同优先级的线程分别占用一段轮流执行

执行的顺序和轮换的时间不可预测

Page 224: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

正确理解优先级和调度

线程调度策略和 JRE运行平台直接相关 Java本身并不直接支持时间片

“ ”不要编写 自私的 线程 在适当的时候通过 yield()方法放弃 CPU yield()方法使线程由运行状态变为就绪状态 yield()方法放弃 CPU后,只有同优先级的线程才能得到 CPU,低优先级的线程仍不能运行

Page 225: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

正确理解优先级和调度

在多任务环境中,如果完全依赖低优先级线程可“ ” 能永远得不到运行机会,称为线程 饿死

线程调度程序可能为低优先级线程分配 CPU,以防“ ”止线程 饿死

优先级只是用来提高多线程的调度效率,并不保证高优先级线程永远优先运行 不要依赖线程的优先级来设计对调度敏感的算法

Page 226: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

正确理解优先级和调度

public class PriorityTest extends Thread { public PriorityTest(String name) { super(name); } public void run() { while(true) { int i; for(int j=0; j<100000; j++) for(int k=0; k<1000; k++) i = j + k; if (getPriority()<NORM_PRIORITY) System.out.println(getName() + " is running."); } }

Page 227: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

正确理解优先级和调度

public static void main(String[] args) { PriorityTest test1 = new PriorityTest("Higer priority thread"); PriorityTest test2 = new PriorityTest("Lower priority thread"); test2.setPriority(4); test1.start(); test2.start(); } }

从运行结果上看,低优先级的线程也有执行的机会。

Page 228: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

线程的调度

当多个线程对同一个对象进行读写操作的时候,如果完全不加控制,可能会出现难以预料的结果

“比较典型的是 生产者 / ”消费者 问题 一个线程(生产者)修改数据 另一个线程(消费者)读取数据 希望生产者每次修改的数据都能被消费者读取,并且不会重复读取

Page 229: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

生产者 /消费者问题

涉及 4个对象 CubbyHole对象,用于保存生产者的修改,并能让消费者读取

Producer对象,产生 0-9,存入 CubbyHole对象中 Consumer对象,读取 CubbyHole对象中的数据 ProdConsTester,测试运行程序

Page 230: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

生产者 /消费者问题

CubbyHole类 public class CubbyHole { private int data; public int get() { return this.data; } public void put(int data) { this.data = data; } }

Page 231: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

生产者 /消费者问题 Producer类

public class Producer extends Thread { private CubbyHole res; public Producer(CubbyHole res) { this.res = res; } public void run() { for (int i=0; i<10; i++) { res.put(i); System.out.println(“Producer put:” + i); try { sleep((int)(Math.random()*100)); } catch (InterruptedException e) { } } } }

Page 232: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

生产者 /消费者问题

Consumer类 public class Consumer extends Thread { private CubbyHole res; public Consumer(CubbyHole res) { this.res = res; } public void run() { for (int i=0; i<10; i++) { System.out.println(“Consumer get:” + res.get()); try { sleep((int)(Math.random()*100)); } catch (InterruptedException e) { } } } }

Page 233: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

生产者 /消费者问题

ProdConsTester类 public class ProdConsTest { public static void main(String[] args) { CubbyHole res = new CubbyHole(); Producer pro = new Producer(res); Consumer con = new Consumer(res); pro.start(); con.start(); } }

Page 234: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

生产者 /消费者问题

分析运行结果可发现两个问题 生产者产生的资源可能没有被消费者获取 生产者产生的资源可能被消费者重复取得

造成这些问题的原因是两个线程在访问同一个对象时没有考虑同步的控制。 当消费者尚未取得资源时,生产者可能已经产生新的资

源,使消费者错过一些资源 当生产者尚未产生新资源时,消费者再次执行 get()方法,

造成资源被重复获取

Page 235: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

引入同步机制

解决前述问题的关键是引入线程之间的同步控制逻辑

通过 synchronized关键字锁定共享对象 方法名前加 synchronized关键字标记 用 synchronized(Object) {…}标记锁定的代码

当线程执行由 synchronized关键字控制的代码时,就锁定了共享对象。其他线程如果需要操作该对象,就必须等待该线程执行完受保护的代码

Page 236: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

新的 CubbyHole public class CubbyHole { private int data; private boolean getable; public synchronized int get() { while (getable == false) { try { wait(); } catch (InterruptedException e) { } } getable = false; notifyAll(); return this.data; }

Page 237: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

新的 CubbyHole public synchronized void put(int data) { while (getable == true) { try { wait(); } catch (InterruptedException e) { } } this.data = data; getable = true; notifyAll(); } }

Page 238: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

更新后的运行结果

Producer put:0 Consumer get:0 Producer put:1 Consumer get:1 Producer put:2 Consumer get:2 Consumer get:3 Producer put:3 Producer put:4 Consumer get:4 Consumer get:5 Producer put:5 Producer put:6 Consumer get:6 Consumer get:7 Producer put:7 Producer put:8 Consumer get:8 Producer put:9 Consumer get:9

Page 239: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

线程的死锁

synchronized关键字可以解决多线程同步问题,但——如果处理不当,可能产生新的问题 死锁

当多个线程分别占用某个资源,并等待其他线程释放该资源时,可能产生死锁

synchronized a() {… b();}synchronized b() {… a();}

Page 240: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

线程的死锁

任何程序员在处理并发线程竞争资源的时候,都必须仔细考虑如何避免死锁 不要设计功能过于复杂,执行时间过长的线程 不要设计过多线程 编写可以检测死锁的代码

Page 241: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

线程的分组

线程组可以将多个线程集中在一个对象中,并同时 操作这些线程(比如全部挂起或杀死)

所有的 Java线程都是某个线程组的一员。当 Java应用程序开始执行时,虚拟机会创建一个名为main的线程组

如果程序没有显示地创建其他线程组并将线程设置其中,则所有的线程都是main 线程组的成员

Page 242: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

创建线程组

可利用 ThreadGroup类创建线程组对象

ThreadGroup myGroup = new ThreadGroup(“my group”);

Thread thread1 = new Thread(myGroup, “thread one”);

Thread thread2 = new Thread(myGroup, “thread two”);

Page 243: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

使用线程组

使用线程组对象操作多个线程: public int activeCount() 返回线程组中活动线程的估计数 public final void stop() 停止线程组中的所有线程 public final void suspend() 挂起线程组中的所有线程 public final void resume() 唤醒线程组中所有被挂起的线程 public final void setMaxPriority(int pri) 设置线程组的最大优先级,组中的线程优先级不得高于该值

Page 244: 第一章  Java 语言概述

欢迎提问

Page 245: 第一章  Java 语言概述

第 9 章 I/O:读和写华中科技大学 IBM技术中心

Page 246: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

I/O与流I/O是程序设计中的重要问题,大部分的应用程序都需要 I/O操作,比如从键盘获得用户输入、在屏幕输出运行结果、对磁盘文件进行读写等等。应用程序只有通过 I/O操作才能实现与用户的交互及数据的处理及

存储在 Java语言中,将不同类型的 I/O抽象

“为流。所谓 流( stream ”) ,可以看作 是数据在文件或程序之间的传递

数据源 程序据

Page 247: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

输入流和输出流

一般来说,流有两种基本形式:输入流和输出流,根据程序是作为数据流的目的端还是源端来划分。程序首先要打开一个

流,才能与数据文件进行通信。通过输入流,程序可以从数据文件读取数据,但不可向输入流中写入数据;反之,通过输出流,程序可以向数据文件中写入数据。程序与其他设备间的 I/O也可以使用流,这时可将设备看作是一个数据文件。

Page 248: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Java I/O流类的组织模式

输 出 流 输 出 流 抽 象 类

文件

缓冲区

管 道

介质

输 入 流 抽 象 类 输 入 流

与介质相关的类

低层次界面

高层次界面

Page 249: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

java.io在 Java开发环境中,主要是由包 java.io中提供的一系列的类和接口来实现输入 /输出处理。而标准输入 /输出处理则是由包 java.lang中提供的类来处理的,这些类又都是从包 java.io中的类继承而来的。

I/O类提供了低层次和高层次的界面。每一种介质都有一对与之相关联的输入输出类,它们提供低层次的面向数据序列(字符、字节)的界面。与介质相关的各个类都分别是输入输出抽象流类的子类,它们通常具有与介质相关的构造器及方法。

I/O抽象类为所有与介质相关的具体输入输出类提供了一个统一的界面。反过来各个具体的与介质相关的输入输出类也扩展了抽象类,通过它们可以实现在具体介质上的输

入输出操作

Page 250: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

I/O操作的一般步骤

构造一个与介质相关的 I/O对象,以提供一种低层次的方法将数据输入或输出到相应的介质;

将与介质相关的对象强制类型转换为它的父类(即抽象 I/O类),并利用该对象构造一个流对象。这样便建立起了流类对象与介质相关对象的关联;

这时就可利用流对象的 I/O方法进行相应介质上的数据读写。

Page 251: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

字节流类

Page 252: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

InputStream类InputStream类定义了一套所有字节输入流

所需的方法方法 描述

read() 将数据读入流中

skip() 跳过流中的若干字节

available() 返回当前流中的可用字节

mark() 在流中标记一个位置

reset() 返回到流中的标记位置

markSupported()

返回一个 boolean值,描述流是否支持标记和复位

close() 关闭流

Page 253: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

OutputStream类

OutputStream类定义了一套所有字节输 出流所需的方法。

方法 描述

write() 写数据到流

flush() 强制将被缓冲的内容写到输出

close() 关闭流

Page 254: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

字符流类

Page 255: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Reader与Writer类 Reader类的相关方法:

void close() void mark(int readAheadLimit) boolean markSupported() int read() int read(char[] cbuf) int read(char[] cbuf, int off, int len) boolean ready() void reset() long skip(long n)

Writer类的相关方法: void close() void flush() void write(char[] cbuf) void write(char[] cbuf, int off, int len) void write(int c) void write(String str) void write(String str, int off, int len)

Page 256: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

流的使用( 1)I/O类型 流 作用

内存

CharArrayReaderCharArrayWriterByteArrayInputStreamByteArrayOutputStream

用来从内存读取数据或向内存写入数据

StringReaderStringWriterStringBufferInputStream

从内存里的某个 String或 StringBuffer读字符或字节

管道

PipedReaderPipedWriterPipedInputStreamPipedOutputStream

实现一个输入、输出管道。管道可用于一个线程的输出连接到另一个线程的输入

Page 257: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

流的使用( 2)

文件

FileReaderFileWriterFileInputStreamFileOutputStream

用于对本机文件系统上的一个件行读写

联结 N/ASequenceInputStream

将多个输入流联结成为一个输入流

对象串行化N/AObjectInputStreamObjectOutputStream

将对象串行化

数据转换N/A DataInputStreamDataOutputStream

以一种与机器无关的格式读写原始数据类型

Page 258: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

流的使用( 3)

计数LineNumberReaderLineNumberInputStream

在读取时记录行数

预览 PushbackReaderPushbackInputStream “带有 回推 (pushback)”缓冲区的输入流

打印 PrintWriterPrintStream 包含便捷的打印方法的流。

Page 259: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

流的使用( 4)

缓冲

BufferedReaderBufferedWriterBufferedInputStreamBufferedOutputStream

缓冲流,用于在读写时进行数据缓冲

过滤

FilterReaderFilterWriterFilterInputStreamFilterOutputStream

过滤流的抽象类接口。数据读写时对数据进行过滤

在字节和字符之间转换

InputStreamReaderOutputStreamWriter 字节流和字符类间的转换桥梁

Page 260: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

文件流

要对本机文件系统上的文件进行读写,需要使用文件流。 Java的文件流类包括字符流的 FileReader、 FileWriter和字节流的FileInputStream、 FileOutputStream。文件流对象的构造需要提供文件名作为参数,也即可以通过文件名来创建文件流。这里的所谓文件名可以是字符串、 File对象或 FileDescriptor对象。

Page 261: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

例程

import java.io.*;class Copy{ private void copy(InputStream in, OutputStream out) throws IOException { byte[] buf = new byte[4096]; int len = in.read(buf); while (len != -1) { out.write(buf, 0, len); len = in.read(buf); } } public void cat(String fsrc, String fdest) { try { InputStream in = new FileInputStream(fsrc); OutputStream out = new FileOutputStream(fdest, true); copy(in, out); out.close(); in.close(); }catch (IOException ex) { System.err.println(ex);} }}

Page 262: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

例程 -cont.public class UseCopy{

public static void main(String[] args){Copy c=new Copy();c.cat(“in.dat”,”out.dat”);

}}

Page 263: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

内存流

为了支持内存上的输入输出, java.io包内提供了一组相关的类: 字节流类—— ByteArrayInputStream

ByteArrayOutputStream StringBufferInputStream

字符流类—— CharArrayReader CharArrayWriter StringReader StringWriter

Page 264: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

例程

import java.io.*;public class ByteArrayOutputStreamTest {     public static void main(String[] args) {

try{ ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); for (int i = 0; i < 1000; i++){

ps.println(i + " ABCDEFGHIJKLMNOPQRSTUVWXYZ"); } long start = System.currentTimeMillis();

FileOutputStream fos =  new FileOutputStream("ByteArrayOutputStreamTest");

baos.writeTo(fos); fos.close();

long stop = System.currentTimeMillis(); System.out.println("time elapsed (milliseconds) = " + (stop - start)); }catch (FileNotFoundException fnfe) { 

System.out.println(fnfe.getMessage()); }catch (IOException ioe) {  System.out.println(ioe.getMessage());  } }

Page 265: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

管道流

管道是用来把一个线程的输出连接到另一个线程的输入。管道输入流作为一个通信管道的接收端,管道输出流则作为发送端。管道流必须是输入输出并用,也就是说在使用管道前,两者必须进行连接。

输出流 ( pi pe)管道 输入流

Page 266: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

为什么要用到管道流?

当某个程序的输出作为另外一个程序的输入时,如果没有管道,就必须为程序提供一个存放中间结果的位置,前一个程序将输出数据写入该位置,而后一个程序再从该位置读出这些数据,这样的做法无疑是低效率的。

通过管道,可以连接程序的输出和输入,直接将前一程序的输出作为后一程序的输入,提高了程序效率。

Page 267: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

管道流的连接方式

java.io中为字符类型和字节类型各提供了一对输入输出管道流类: PipedReader/ PipedWriter和 PipedInputStream/PipedOutputStream。

管道流的连接方式有两种,以PipedInputStream/PipedOutputStream为例: 在构造方法中进行连接:PipedInputStream(PipedOutputStream pos);

PipedOutputStream(PipedInputStream pis); 通过各自的 connect()方法连接:

在类 PipedInputStream中, connect(PipedOutputStream pos);

在类 PipedOutputStream中, connect(PipedInputStream pis);

Page 268: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

例程

class PipedExample { public static void main(String args[]) throws IOException{ byte dataA = 123, dataB= 321; PipedInputStream pis = new PipedInputStream(); PipedOutputStream pos = new PipedOutputStream(pis); System.out.println("PipedInputStream"); try{ pos.write(dataA);

pos.write(dataB); System.out.println((byte)pis.read()); System.out.println((byte)pis.read());

}finally{ pis.close(); pos.close(); } }}

Page 269: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

过滤器流

在某些情况下,对于由程序写入或读取的数据, 需要在写入或读取之前对其进行处理或者过滤

总的来说,过滤器的作用是对相关输入输出流中的数据进行处理,而对于程序而言,这些过滤器是透明的。

介 质介 质

输出流

输入流

过滤器

Page 270: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

过滤器流类

类型 类 作用

字节

FilterInputStreamFilterOutputStream 字节类型的过滤器类的抽象父类

BufferedInputStreamBufferedOutputStream 缓冲过滤器流,用于提高输入输出效率

PushBackInputStream “ ”允许将已读取的数据 压回 到流中

GZIPInputStreamGZIPOutputStreamZipInputStreamZipOutputStream

对数据进行 zip格式或 gzip格式的压缩

字符

FilterReaderFilterWriter 字符类型过滤器类的抽象父类

BufferedReaderBufferedWriter 缓冲过滤器流,用于提高输入输出效率

PushBackReader “ ”允许将已读取的数据 压回 到流中

LineNumberReader 用计数器统计从输入中读取的数据行数

Page 271: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

例程

import java.io.*; public class ReadLineTest { public static void main(String[] args) { try { BufferedReader br = new BufferedReader(new FileReader(args[0])); String line = null; int i = 0; while((line = br.readLine()) != null) { i++; System.out.println(i + ": " + line); } br.close(); }catch(Exception e) { e.printStackTrace(); } }}

Page 272: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

对象的串行化

所谓对象串行化是指读写对象的过程,其关键之处在于以串行的流的形式来表示结构化的对象。为了实现完整对象的输入输出, java.io包中提供了两个类: ObjectOutputStream和ObjectInputStream。这两个流类与其他的字节流类的功能类似,其特殊之处在于通过它们可以读写对象。对象的串行化通常在下面两个方式下使用: 远程方法调用( RMI ——) 在远程方法调用时,需要在客户机与服务器之间传递各种对象。

——对象持久性保存 允许对象在创建它们的程序的生命周期结束后仍然存在保存,供以后的程序调用。

Page 273: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Serializable接口

并非所有对象都是可串行化的,如果要对某对象进行串行化,该对象的类必须实现Serializable 接口

Serializable接口是一个空接口,也就是说,它不包含任何方法的声明,该接口的作用只是表明这个类的对象可以被串行

Page 274: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

随机文件处理

使用流的形式对文件进行读写必须顺序进行,也就是说这些文件流的数据必须按先后次序进行处理。在对某些顺序存储访问介质,例如磁带等进

行访问时,这样的文件流方式非常有用随机文件存取提供了一种更灵活的文件读写方式,它允许对文件的内容进行非顺序的访问。在

“ ”这里, 随机 是指所存取的数据不需要与以前存取过的历史数据有任何的关系。使用随即文件存取方式可以在打开一个文件后同时进行读写操作,并且可以移动文件指针使其指向文件中的任

何位置

Page 275: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

随机存取文件的结构

在文件内部,文件被分成固定长度的数据块(记录)。从概念上来说,文件可以看作是一个记录数组。文件指针的移动是以记录为单位的。

文件指针

· · ·记录 记录 记录 记录 记录 记录 记录

文件

Page 276: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

文件类 FileFile类的核心概念是封装用户文件系统中的某个文件或目录,它包含许多用于执行文件常规操作的方法以及检查、访问、删除、创建、更改指定的文件或目录

File类的构造函数有三个,分别根据文件名、文件路径与文件名、文件对象 (目录 )与文件名创建实例: public File(String path) public File(String path,String name) public File(File dir,String name)

Page 277: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

RandomAccessFile类RandomAccessFile类的构造函数使用了两个参数,第一个参数表示要操作的文件,可以使用字符串类型的文件名也可以使用一个文件对象;第二个字符串类型的参数 mode表示了对文件的操作方式: mode ”为 r” 时表示可以从文件读取;mode ”为 rw” 时表示既可以从文件读取也可以

向文件写入RandomAccessFile类通过实现 DataInput和DataOutPut的方法来实现文件数据的读写,这些方法允许使用二进制编码形式将基本的 Java类型写入或读出文件。在 RandomAccessFile类中还提供了一些操作文件指针的方法,如通过 seek方法可以将文件指针移动到其参数所制定的位置。

Page 278: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

例程

import java.io.*;public class FileTest {  public static void main(String[] args) throws IOException {         RandomAccessFile raf = new RandomAccessFile("foo.txt", "rw");  try {             Writer out =  new OutputStreamWriter(new FileOutputStream(raf.getFD()), "UTF-8");  out.write("Hello World!!");             out.flush();              raf.seek(6);              out.write("Java");         out.flush();         }finally {             raf.close();         } }

Page 279: 第一章  Java 语言概述

第十章 图形用户界面华中科技大学 IBM技术中心

Page 280: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

Contents

界面布局

事件处理过程

常用的图形组件

Swing和 AWT

图形用户界面基本元素

Page 281: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

图形用户界面基本元素

图形用户界面( GUI )

可以使程序提供独特的视觉效果 提高软件易用性 使用鼠标和键盘操作 $javahome$/demo/jfc/SwingSet2

Page 282: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

图形用户界面基本元素

常见的图形界面元素 基本组件

• 文本框、按钮、输入框• 单选 /多选按钮、下拉框 /复选框• ……

容器• 可放置基本组件的组件• 窗体、面板、框架• 所有的组件都必须存在于容器之中• 顶层容器 Container

Page 283: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

AWT和 Swing

AWT- Abstract Window Toolkit 图形界面是平台相关的 AWT是重量级的,依赖本地代码实现 不同平台外观有差异

Swing-轻量级纯 Java的图形库 基于 AWT,更丰富,功能更强大 不同平台外观一致 牺牲了性能

SWT

Page 284: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

常用的图形组件

AWT java.awt.* Label、 Button、 List、 TextField… Frame、 Panel、 Container

Swing javax.swing.* JLabel、 JButton、 Jlist、 JTextField… JFrame、 JPanel

不要在容器中混合使用 AWT和 Swing组件

Page 285: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

常用的图形组件

组件类名 描述

JLabel 不可编辑的文本行(可带图标)

JTextField 可编辑的文本行

JButton 按钮

JCheckBox 复选框

JRadioButton 单选框

JComboBox 下拉框

JPanel 面板

JFrame 框架

更多组件可参考 javax.swing.*

Page 286: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

图形组件测试

import java.awt.*; import javax.swing.*;

public class GUITest extends JFrame { private JLabel label; private JButton button; private JCheckBox checkbox; private JRadioButton rbutton; private JTextField textfield; private JComboBox cbox; private JList list;

Page 287: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

图形组件测试

public GUITest() { super("GUI Test"); Container container = getContentPane(); container.setLayout(new FlowLayout());

label = new JLabel("Im JLabel"); button = new JButton("Im JButton"); rbutton = new JRadioButton("Im JRadioButton"); textfield = new JTextField(10); textfield.setText("Im JTextField"); checkbox = new JCheckBox("Im JCheckBox"); cbox = new JComboBox(); cbox.addItem("JComboBox item 1"); cbox.addItem("JComboBox item 2"); list = new JList(); String[] data = {"JList data 1","JList data 2", "JList data 3"}; list.setListData(data);

Page 288: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

图形组件测试

container.add(label); container.add(button); container.add(checkbox); container.add(rbutton); container.add(textfield); container.add(cbox); container.add(list); setSize(300,200); setVisible(true); } public static void main(String[] args) { GUITest test = new GUITest(); test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }

Page 289: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

图形组件测试

运行结果

Page 290: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

事件驱动

图形界面程序是通过事件来驱动的 当用户对图形组件进行操作时产生事件 如鼠标点击按钮、在输入框中输入文字等 事件对象用于记录事件详细内容 java.awt.AWTEvent

Page 291: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

事件处理模型

事件处理模型中的三要素 事件源对象

• 即产生事件的图形组件如按钮、文本框等 事件对象

• 记录事件的对象,由系统产生 事件监听对象

•捕获并处理事件的对象

程序员的工作 将事件监听对象注册到事件源对象 编写处理事件的代码

Page 292: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

常用的事件类

GUI事件类层次结构

java.lang.Object

java.awt.AWTEvent

ActionEvent

ItemEvent

AdjustmentEvent

ComponentEvent

java.util.EventObject

ContainerEvent

PaintEvent

FocusEvent

WindowEvent

InputEvent

KeyEvent MouseEvent

Page 293: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

常用的事件监听接口

事件监听接口层次结构

java.util.EventListener

ActionListener

ComponentListener

AdjustmentListener

ContainerListener

MouseListener

TextListener

ItemListener

FocusListener

KeyListener

MouseMotionListener

WindowListener

Page 294: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

事件处理示例

import java.awt.*; import java.awt.event.*; import javax.swing.*; public class EventTest extends JFrame { private JButton button; public EventTest() { super("Event Test"); Container container = getContentPane(); button = new JButton("Click Me"); EventHandler handler = new EventHandler(); container.add(button); setSize(200,100); setVisible(true);

button.addActionListener(handler); }

Page 295: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

事件处理示例

class EventHandler implements ActionListener { public void actionPerformed(ActionEvent event) { ((JButton)event.getSource()).setText("Im Clicked"); } }

public static void main(String[] args) { EventTest app = new EventTest(); app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }

Page 296: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

常见的事件类和监听接口

不同的事件源根据用户的操作可能产生不同的事件对象,并由相应的事件监听对象处理

事件源 产生的事件 需要实现的监听接口JButton

ActionEvent ActionListener

JCheckBoxJRadioButton

JTextField

TextEvent TextListenerKeyEvent KeyListener

JComboBoxItemEvent ItemListener

JList

Page 297: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

鼠标事件类和监听接口

所有的图形组件都能产生鼠标事件 java.awt.event.MouseEvent

处理不同的鼠标操作应实现不同的接口 鼠标点击、鼠标进入组件、鼠标离开组件

•实现 MouseListener接口 鼠标在组件中移动和拖动

•实现 MouseMotionListener

查看 Java API文档,实现这些接口应该定义哪些方法?

Page 298: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

事件适配器

由 JavaAPI提供的实现了相应事件监听接口的抽象类,可直接使用而无需定义额外的事件处理类,从而简化事件处理代码 addMouseListener(new MouseAdapter() { mouseClicked(MouseEvent event){ // … } });

Page 299: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

界面布局

设计图形界面时,程序员应该考虑组件在容器中的位置、大小和组件之间的排列方式

如果没有使用布局管理器,程序员需要确定每个组件的大小和在容器中的坐标: JButton btn = new JButton(“Ok”);

btn.setBounds(10, 20, 60, 20); add(btn);

当窗口大小改变时,组件不会自动调整位置和大小

Page 300: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

布局管理器

Java使用布局管理器简化组件布局工作 决定图形组件的排列形式 实现接口 java.awt.LayoutManager

使用布局管理器的好处 当程序窗口尺寸改变时,布局管理器能自动调整组件的位置和大小

Page 301: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

常用的界面布局形式

常用的布局管理器 FlowLayout BorderLayout BoxLayout CardLayout GridLayout GridBagLayout

通过容器组件的 setLayout()方法设置容器中的组件排列形式,如: setLayout(new FlowLayout());

Page 302: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

FlowLayout

最简单的界面布局方式,从左至右、从上至下按顺序依次摆放组件: setLayout(new FlowLayout()); add(button1); add(button2); add(button3); add(button4); add(button5);

Page 303: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

BorderLayout

按东南西北中五个区域摆放组件,通常作为窗口主框架 setLayout(new BorderLayout()); add(“North”, button1); add(“West”, button2); add(“East”, button3); add(“South”, button4); add(“Center”, button5);

Page 304: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

GridLayout

各组件占用相等的格空间 setLayout(new GridLayout(3, 2)); add(button1); add(button2); add(button3); add(button4); add(button5);

Page 305: 第一章  Java 语言概述

华中科技大学 IBM技术中心

HUST & IBM Computer Tech. Center

GridBagLayout

最复杂、最灵活的布局方式,将容器空间划分成网格,每个组件可占用多个网格。通常还需要使用 GridBagConstraints对象设置组件占用的格数和方位。加入组件前,需要调用布局管理器对象的 setConstraints()方法设置组件的显示约束。

Page 306: 第一章  Java 语言概述

欢迎提问

Page 307: 第一章  Java 语言概述