Java程序设计-书上重点总结

第一章

Java是一种解释型的程学设计语言,即Java源程序需要通过Java编译器先进行编译生成一种称为字节码的二进制文件,之后用Java解释器来解释执行这种字节码文件。

先通过编译器编译,生成字节码文件,再到对应的解释器执行

第二章

  • 封装是把对象的属性和行为组合成为一个独立的单位或者部件,并尽可能隐蔽对象的内部细节,而只保留必要的对外接口,使之与外部发生联系。
  • 多态性描述:同一个信息可以根据发送消息对象的不同产生多种不同的行为方式。

Java通过方法重写(方法覆盖),方法重载和接口来实现多态。

*号表示把包中所有的类都引入本程序中

关键字Public修饰的类可以被其他类所引用,Java规定在一个源程序文件中可以有0个或1个用public修饰的class,且这个public class修饰的类名必须与.java源程序文件名完全一致。

InputStream、Outputstream类与Reader、Writer类相比较,它们具有类似的方法,但InputStream、Outputstream类的方法是基于字节、字节数组上的方法,Reader、Writer类的方法是基于字符、字符数组或者字符串上的方法。

编译时异常必须处理,(throws IOException)

Integer类中的ParseInt(String str)方法,该方法将字符串型数据str转成int型

第三章

Java的基本数据类型包括整数型、浮点型、布尔型(true,false)、字符型。

整数类型(int、short、long、byte)

浮点类型(float、double)

布尔类型(Boolean)

字符类型(char)

字符串常量和字符常量,一个是双引号一个是单引号。

自动转换:Java会按从定义域小的类型值自动转换到定义域大的类型值。

强制转换:double d = 123.45;int nx = (int) d;

第四章:

数组:

数组的创建:

数组名 = new 数组元素的类型 [数组的长度]

数组的初始化 : such : int num[] = {2,5,4,1};

数组的复制:

int num[] = {9,8,3,0,2};

int numCopy[] = num;

可以直接赋值

还可以用System类中的arraycopy()方法 :

System.arraycopy(num,int srcpos,numCopy,int destpos,length);

该方法将指定源数组num中的length个元素复制到目标数组numCopy中,复制从源数组的指定的位置srcpos开始,把源数组中的元素复制到目标数组中,目标数组的位置从destpos位置处开始向后。

数组长度用length 数组名.length

java中可以对二维数组的每一行来初始化,即二维数组中允许各行有不同的元素个数。

数组元素的填充方法:public static void fill(int a[],Int Val);

public static void fill(int a[],int fromP,int toP,int Val);

数组元素的查找方法:public static int binarySearch(int a[],Int Val);

字符串:

声明字符串:String stringname;

字符串的创建格式:

stringname = new String(字符串常量)

或者 stringname = 字符串常量
声明和创建可以一步完成,例如:

String str = new String (”student“);

或者 String str = ”student“;

(StringBuffer只能用第一种声明和创建方法,String可以用两种)

StringBuffer和String对区别:String是用来创建字符串常量,StringBuffer是用来创建字符串变量。

取得字符:

public char charAt(int index);

用于获取字符串中指定位置index处的字符(从0开始计算),返回的是字符类型的数据

char c = str.charAt(7);

取得字串:

public String substring(int beginIndex);(指定于beginIndex处到末尾。)

public String substring(int beginIndex,int endIndex);(从beginIndex到endIndex - 1处)

比较两个字符串是否相等,用equals()

public boolean equals(Object anObject);

将其他类型转化为字符串,用valueof

public static String valueOf(type x)

StringBuffer中有关的方法

对字符串的内容动态修改。

增加字符:可以接受任意类型的数据

public StringBuffer append(anytype v);

such:str1 = str1.append(bFlag);

插入字符:

public StringBuffer insert(int insertP,anytype v);

insert()方法可以被重载,可以接受任何类型的数据转换成字符串。

删除字符用delete,第一个形参是起始位置,第二个是终止位置

替换字符用replace,第一个形参是起始位置,第二个是终止位置,第三个是替换的String

清空字符用setLength(),形参是字符串缓冲区的长度,设为0就可以清空。

字符串反转用reverse(),算法中经常用到。

第五章

类:

类的定义:

类中的数据称为成员变量,有时也称为属性、数据、域。用来描述对象动态特征(行为)的一个操作序列,称为类的成员方法。

类的声明的格式如下:

[<修饰符>]class<类名>[extends<父类>][implements<接口名>]

extends说明类的父类,一般形式为extends<父类名>。在java语言中,如果在类的说明中无extends,则隐含地假设其父类为Java.lang.object类。

说明常量:

用final说明对变量可以当作一个常量使用,可以在任何作用域声明一个变量。

final修饰的,只能先定义,再初始化,不然就会出错误。

java的默认修饰符:访问权限是允许类自身及在同一个包中对所有类对变量访问。

成员方法:

[方法修饰符]<方法返回值类型><方法名>([<参数列表>]){方法体}

用final修饰说明这是最终方法,不能被重载,只能被继承。

用static说明方法为静态方法,也称为类方法。在使用这个方法时不需要初始化该方法所在的类。static类型方法也不能被它的子类所重载。

用abstract说明方法是抽象方法,该方法只用方法说明,没有方法体。方法体在该抽象方法所在类的子类中被具体实现。抽象方法所在的类被称为抽象类。

用synchronized说明方法是同步方法,主要用于多线程程序设计,用于保证在同一时刻只有一个线程访问该方法,以实现线程之间的同步。同步方法是实现资源之间协商共享的保证方式。

方法除了void都要返回值,用return实现(c++基础)

构造方法:(重点,考填空,判断,选择)

构造方法是一种特殊的方法,主要用于为类的方法中变量赋初始值。当用new创建一个类的新的对象时,构造方法就立刻执行。构造方法名字必须与类名相同。除了构造方法,在类中不能出现与类名相同的方法。构造方法的语法为:

public 类名([参数列表])

{

   [语句序列];

}                                     

构造方法有以下特点:

  1. 构造方法没有返回值类型,甚至没有void,其修饰符只能是访问访问控制修饰符。
  2. 构造方法不能从父类中继承。
  3. 构造方法可以重载,一个类可以有任意多个构造方法。不同对象根据参数的不同状态选择合适的构造方法。
  4. 构造方法不能直接通过方法名引用,必须通过new运算符。
  5. 在构造方法中可以调用当前类和其父类的另一个构造方法,但必须是方法题的第一条语句。使用当前类的构造方法用this来引用,使用其父类的构造方法用super来引用。

对象释放:

用new创建新的对学习,java就会分配内存空间给他,如果其不再使用了,就把它的值设置为null,就使得它变成了无用对象,java系统通过垃圾回收器GC(Garbage Collector)周期性地释放无用对象所使用的内存,完成对象的清除工作。

GC在java中是作为一个线程来允许的,即调用System.go(),另外,在java系统开始运行时,会自动调用一个名为finalize()的方法,使它清楚对象所占的内存,比C++中用delete和C中用free来释放内存的措施好得多。

方法重载:重点

在java中可以创建名字相同,但是参数和返回值不同的几个方法,很简单,就不写了,定义方法时候把参数换成自己需要的就好了。构造方法重载一样的。

内部类:

在类内部可以定义成员变量和方法,也可以定义另一个类,在8.3讲了。

访问控制符和封装:

(自己理解就好,写不清楚的)

继承:重点           

面向对象程序设计的三个主要特性为封装性、多态性和继承性。

子类格式按定义为类的格式。如果有如下类A声明:

class 类名A[extends 父类B][implements<接口名>]

{
<成员变量的声明>

<成员方法的声明及实现>

}

则说明新定义的类A是父类B的子类。如果默认extends子句,则该类为java.lang.Object的子类。子类可以继承父类中的访问权限为public、protected等的成员变量和方法,但不能继承访问权限为private的成员和方法。有了继承机制,在编写程序时,就可以先定义一个包含公共变量和公用方法的类作为父类,再在此基础上创建具有专用变量的和专用方法的子类。子类一方面继承父类中已有的变量和方法(普遍性原则),另一方面子类还可以增加父类中所没有的变量和方法(特殊性原则)。

(自己看书P118,怎么继承的写的很清楚)

变量隐藏和方法覆盖:

子类继承父类后,如果出现子类的成员变量和父类的成员变量同名,那么子类将把父类的成员变量隐藏起来。在这种情况下,子类使用的变量是它自己的变量,而不是父类的成员变量,那么子类如果要调用父类的变量,则必须借用关键字super。另外一种情况是子类的方法名与父类的方法名相同(返回值的类型和入口参数的数目、类型均相同),那么在子类中重新改写了父类的同名方法,即子类方法覆盖(overriding)了父类的方法。通过方法重写,子类可以重新实现父类的某些方法,使其具有自己的特征。

重载:overloading,是指在同一个类中,定义多个名称相同的,但参数个数或类型不同的方法,Java根据参数的个数或类型,调用相对应的方法。

覆盖:overriding,是指在子类中,定义名称、参数个数与类型均与父类相同的方法,用以重写父类中的方法的功能。

Super:

三种情况使用:

  1. 用来访问父类中被覆盖的方法;
  2. 用来调用父类中的构造方法;
  3. 用来访问父类中被隐藏的成员变量;

调用构造方法遵循以下的几条规则:

  1. 当一个类创建对象时,可以调用该类的父类的构造方法。调用父类的构造方法很简单,只要在类的构造方法的方法体中,第一条为super语句就可以了。super可以调用父类的任何一个带入口参数的构造方法。
  2. 如果一个类的构造方法中第一条语句没有用super来调用父类的构造方法,则编译器也会默认在构造方法中用super()语句调用父类的无参构造方法。
  3. 如果某个类的构造方法的第一条语句时用this来调用本类的另外一个构造方法,那么java系统就不会默认这个构造方法调用父类的构造方法。
  4. 一个构造方法是用this语句调用本类的另一个构造方法时,如果被调用的构造方法又是调用父类的构造方法而又没有用super语句,那么编译器会默认它含有super()语句。此时,父类中若不存在无参的构造方法,也将会导致编译出错。

this是java的一个关键字,表示每个实例对象指向自己的作用,一般只能用在实例方法和构造方法中,不能出现在类方法中。在方法中this通常用在下列两种情况下:

  1. 如果方法参数或局部变量与实例成员域名相同,同名的实例成员域变量就会被隐藏,可通过this.variableName方式进行对成员域变量显式的访问。
  2. 返回实例对象本身的引用 书P121

运行时多态有以下两条原则:

  1. 对子类的一个实例,如果子类重写(覆盖)了父类的方法,则运行时系统就调用子类的方法。
  2. 如果子类继承了父类的方法,则运行时系统仍调用父类的方法。

Java的接口机制提供了很多和多重继承相似的特性,同时又避免了复杂性。

对象类型转换:
一般是子类转父类的,子类对象的类型可以向上转换成它的父类类型,这个转换过程是安全的。

抽象类:

通过继承,可以从原有的类派生出新的类,子类不仅可以拥有父类的功能,同时也可以拥有新的功能。实际上在Java语言中,除了上述机制之外,Java也可以创建专门的类用来当作父类,这种类称为抽象类(abstract class)。抽象类有点类似“模板”的作用,其目的是要你根据它的格式来修改并创建新的类。不能够通过抽象类直接创建对象,只能通过抽象类派生新的类,再由新类创建对象。定义一个抽象类的格式为:

abstract class 类名称

{

声明数据成员;

返回值的数据类型 方法名称(参数列表){; //定义普通的方法

}

abstract 返回值的数据类型 方法名称(参数列表);//定义抽象的方法

}

不是所有方法都可以声明为抽象的,私有方法和静态方法是不能声明为抽象的。

在类中声明一个变量或方法时,还可以指定它为实例成员或类成员,其格式为:

static 类型 变量名;

static 返回值类型 方法名 ([参数列表])

  1. 实例方法必须由实例对象来调用;
  2. 类方法可以由实例对象调用,也可以通过类名直接调用;
  3. 在类方法中不能使用this和super。

 另外,由static引导的一对大括号的语句组构成静态初始化块,它的作用是完成类的初始化工作。类的静态初始化按从左到右、从上到下次序进行。静态初始化与构造方法是不同的,主要表现为:

  1. 构造方法是对每个新创建的对象进行初始化,而静态初始化是对类自身进行初始化工作。
  2. 构造方法是在用new运算符产生新对象时由系统自动执行,而静态初始化是当所属的类加载到内存中由系统调用执行。
  3. 与构造方法不同的是,静态初始化不是方法,没有方法名、参数列表和返回值。

final:

Final 和abstract不能同时修饰一个类。

Java的名字空间和包

通常将自己及他人编写好的类按照功能分类、整理成一个个单元,也就是包。

所有的变量和方法都是在类中定义,并且是类的重要组成部分,而每个类又是包的一部分,因此每个java变量或方法都可以用全限定的名字表示。包括包名、类名、域名三部分,之间用“.”分隔。

如果Java文件中有多个类定义,则只能有一个类可以定义为public,并且这个类的名字必修与程序名一致。

包可以嵌套使用。

接口:重点,可实现多态,会建立实现

java语言不支持多重继承,即一个子类只能有一个父类,若子类需要继承多个父类,这就需要使用接口。为了解java语言的接口,先来看一个接口简单应用引例:

public interface interfacename extends superinterfacename

{

static final double PI = 3.14; //说明常量

public double Area(); //状态方法

double bulk(); //默认状态方法

}

该例子中定义了一个接口,在接口体中定义了常量PI、抽象方法area()和bulk()。

接口是Java所提供的另一种重要功能,它的结构和抽象类非常相似。接口是一种特殊的类,但接口与类存在着本质的区别。类有它的成员变量和成员方法,而接口却只有常量和抽象方法,也就是说接口的成员变量必须初始化,同时接口中的所有方法必须全部声明为abstract方法,一个类可以有多个接口。Java语言通过接口使得处于不同类甚至互不相关的类具有相同的行为。

接口的声明:

接口通过关键词interface来定义,接口定义的一般形式为:

[接口修饰符]interface<接口名>[extends<父类接口列表>]

{

//接口体

}

接口体中包括接口中所需要说明的常量和抽象方法。

被继承的类接口称为父类接口,当有多个父类接口时,用逗号“,”分割。

接口体中包括接口中所需要说明的常量和抽象方法。由于接口体中只有常量,所以接口体中的变量只能定义为static和final型,在类实现接口时不能被修改,而且必须用常量初始化。接口体中的方法说明与类体中的方法说明形式一样,由于接口体中的方法为抽象方法,所以没有方法体。抽象方法的关键字abstract是可以省略的,同时成员变量的final也可以省略。接口体中方法多被说明成public型。

接口的实现:

在前面所介绍的类声明中,用implements子句表示一个类用于实现某个接口。一个类可以同时实现多个接口,接口之间用逗号“,”分割。在类体中可以使用接口中定义的常量,由于接口中的方法为抽象方法,所以必须在类体中加入要实现接口的方法。如果一个接口是从别的一个或多个父接口中继承而来,则在类体中必须实现该接口及其父接口中的所有方法。在实现一个接口时,类中对方法对定义要和接口中的相应方法的定义相匹配,其方法名、方法的返回值类型、方法的访问权限和参数的数目与类型信息要一致。

P130例子。

第六章

异常的概念:

即使在编译时没有产生错误信息,在程序运行时也会出现不正常的现象,如死循环、非正常退出等,称为运行错误。根据错误性质将运行错误分为两类:错误和异常。

致命性错误:如程序进入死循环,或递归无法结束,或内存溢出,这类现象称为错误。错误只能在编程阶段解决,只能依靠其他程序干预,否则会一直处于非正常状态。

非致命性异常:如运算时除数为0,或操作数超出范围,或打开一个文件时发现文件并不存在,或欲装入的类文件丢失,或网络连接中断等,这类现象称为异常。

Java语言的异常处理方法有下列主要优点:

  1. Java通过面向对象的方法进行异常处理,把各种不同的异常事件进行分类,体现了良好的层次性,提供了良好的接口。
  2. Java的异常处理机制使得处理的异常的代码和“常规”代码分开,减少了代码的数量,同时增强了程序的可读性。
  3. Java的异常处理机制使得异常事件可以沿调用栈自动向上传播,而不像C/C++语言中通过函数的返回值来传播,这样可以传递更多的信息并且简化代码的编写。
  4. 由于把异常事件当成对象来处理,利用类的层次性我们可以把多个具有相同父类的异常统一处理,也可以区分不同的异常分别处理,使用非常灵活。
  5. Java异常处理机制为具有动态运行特性的复杂程序提供了强有力的控制方式。

异常处理:

Java中的所有异常都是由Throwable类的子类生成的对象,所有的异常类都是Throwable类的子类或者子类的子类。

Exception类:

有些异常在编写程序时是无法预料的,如中断异常、非法存取异常等。为了保证程序的健壮性,Java要求必须对可能出现这些异常的代码使用try-catch-finally语句进行捕获并对它们进行处理。

IOException是输入/输出异常

try-catch-finally语句:

语法格式为:

try{

statements;//可能产生异常的语句

}

catch(Throwable-subclass e)//异常参数

{

statements;//异常处理程序

}

finally

{

statements;//一定会运行的程序代码

}

上述的语法依据下列的顺序来处理异常:

  1. try程序块中若有异常发生时,程序的运行便中断,并抛出“由异常类所产生的对象”。
  2. 抛出的对象如果属于catch()括号内欲捕捉的异常类,则catch会捕获此异常,然后进入catch程序块里继续运行。
  3. 无论try程序块是否捕获到异常,或者捕获到的异常是否与catch()括号内的异常相同,最后一定会运行finally块里的程序代码。finally块运行结束后,程序继续运行try-catch- finally块之后的代码。

throw和throws语句

throw和throws语句不同,前者是一个独立的语句,而后者总是和方法定义相结合起来使用。有时候并不需要用这个方法本身来处理异常,而是可以把异常往上移交给调用该方法的方法来处理,这时要用throws语句实现。

如果在一个方法中产生了异常,但是该方法并不处理它产生的异常,而是沿着调用层次向上传递,交由调用它的方法来处理这些异常,这就是声明异常。

声明异常的方法是在产生异常的方法名后面加上要抛出(throws)的异常的列表,throws语句要和方法定义结合起来使用,格式为:

返回类型 方法名([参数列表])throws异常列表;

FileInputStream类中的read()方法是这样定义的:

 public int read () throws IOException{…}

  • Applet小程序 考综合题

Applet概述:第1章中曾提到过Java语言可用来编制两类程序,即Java应用程序和Applet小程序、前面的章节阐述了Application的应用,本章将介绍Java Applet,即Java小程序。

Applet程序与Application的区别主要在于其执行方式的不同。Applet既可在支持Java的Web浏览器中运行,也可以使用Appletviewer运行;Applet必须嵌入到一个HTML语言文件中,通过编写HTML语言代码告诉浏览器载入何种Applet及如何运行;而Application是从其中的main()方法开始运行的。P161

“沙箱”机制:(禁止applet执行下列操作)

  1. 在运行时调用其他程序
  2. 文件读/写操作
  3. 装载动态链接库和调用任何本地方法
  4. 试图打开一个socket进行网络通信,但是所连接的主机并不是提供applet的主机

Java Applet和Java Application的主要区别

  1. application是独立运行的,Applet是嵌入到Web页面上的,必须在支持Java的浏览器中运行。
  2. Application中必定含有一个并且只有一个方法main()。Applet中无main()方法,且是从java.applet.Applet继承的。
  3. Application是可以进行各种操作的程序,applet对于站点的磁盘文件不能读写。

Applet从建立到执行可分为四步:

  1. 用Java语言编写一个applet源程序。
  2. 把applet源程序编译成字节码。
  3. 将applet字节码嵌入Web页面,即设计一个包含Applet到HTML文件。
  4. 用支持Java的浏览器运行、浏览。

HTML代码的基本结构:

HTML是一种分层语言,各种标记均成对出现,用“<>”括起来,开始和结束标记的区别在于结束标记以“/”开头,标记字母忽略大小写。每个页面都必须包含相同的整体结构,它的结构如下:

<HTML>

<HEAD>…

<TITLE>…</TITLE>

<HEAD>

<BODY>…

<HR>

</BODY>

<HTML>

Applet程序可以在Appletviewer环境下运行或在Web浏览器中加载,但必须通过在HTML中定义的<APPLET>标记才能实现。<APPLET>标记包含在<BODY></BODY>之间

P167程序

第八章 图形用户界面应用

AWT和Swing简介:

Java语言的抽象窗口工具包AWT中包含了许多类来支持GUI设计。AWT由Java语言的java.wat包提供,该包中有许多用来设计GUI的组建类,如按钮、菜单、列表、文本框等,同时它还包括窗口、面板等容器。

Java.awt包中除了包含Font、Color、Graphics、Menu、Component等子类外,还包含来两个重要的概念:组建类(Component)和容器类(Container)。

Container也是一个类,实际上是Component的子类,因此容器本身也是一个组件,具有组件的所有性质,但是它的主要功能是容纳其他组件和容器。

Java语言把由Container的子类或间接子类创建的对象称为一个容器。Java语言的Component类提供一个public add()方法,可以向容器中添加组件,即一个容器可以调用这个方法将组件添加到该容器中。Java的图形用户界面的最基本组成部分是组件,组件是一个可以以图形化的方式显示在屏幕上并能与用户进行交互的现象,如一个按钮、一个标签等,组件不能独立地显示出来,必须将组件放在一定的容器中才能显示出来。

Applet类不是Java.awt包中的类,图中只是说明它是Panel的子类,是Container的间接子类,即由Applet类创建的对象也是一个容器。

在复杂的图形用户界面设计中,为了使布局更加易于管理、具有简洁的整体风格,一个包含了多个组件的容器本身也可以作为一个组件加到另一个容器中去,容器中再添加容器,这样就形成了容器的嵌套。

每个容器都有一个布局管理器,当容器需要对某个组件进行定位或判断其大小尺寸时,就会调用其对应的布局管理器。

Swing组件及其之间的层次关系:

Swing是Java基础类库(JFC)提供的新的图形界面类库,在JFC的新特性中,它是其中最主要的部分。Swing为基于窗体的应用开发设计提供了一套精美、丰富的基本组件,以及一个能使图形用户界面GUI独立于特定平台的显示框架。用Swing组件设计设计的程序比用AWT程序具有更加优美的外观感受。

Swing是一个扩展的AWT,它提供了一个远大于AWT的综合的组件集合,并引入了新的概念和性能。在Javax.swing包中,定义了两种类型的组件;顶层容器(JframeJappletJdialog和Jwindow)和轻量级组件。Swing组件从AWT的Container类继承而来,增加Swing组件后类层次结构如图8.2所示:(P178)

布局管理:

要为应用程序设计精美的外观,设计和控制窗口组件在容器中的位置和相互关系,即必须学习布局设计知识。当在Applet程序中使用了3个或更多的组件时,布局管理器便是不可缺少的,有了它们就可快速组织好屏幕元素的布局。

Java.awt包中共定义了5种布局管理器类,它们分别是FlowLayout、BorderLayout、CardLayout、GridLayout和GridBagLayout,每个布局管理器类对应一种布局策略。

顺序布局:

FlowLayout是容器Panel和Applet程序默认使用的布局管理策略,遵循这种策略的容器将其中的组件按照加入的先后顺序从左向右排列,一行排满之后就到下一行继续从左至右排列,每一行中的组件都居中排列。(当容器的大小发生变化时,用FlowLayout管理的组件会发生变化。其变化规律是:组件的大小不变,但是相对位置会发生变化。

边界布局:

BorderLayout是Window、Frame和Dialog的默认布局管理器,也是一种简单的布局策略,它把容器内的空间简单地划分为东、西、南、北、中5个区域,每加入一个组件都应该指明把这个组件加在哪个区域中。

网格布局:

GridLayout是使用较多的布局管理器,其基本布局策略是把容器的空间划分成若干行乘若干列的网格区域,组件就位于这些划分出来的小格中。

  1. 创建Grid Layout对象作为布局管理器。
  2. 调用容器的方法add()将组件加入容器。

事件处理

事件与事件处理方法:

java.awt.event包括了代表各种事件的类,主要包括以下几类:

  1. 事件。在java.awt.event包中以Event结尾的类都属于事件类,例如ActionEventWindowEvent、MouseEvent和KeyEvent。
  2. Listener。包中还定义了一些可以用事件Listener实现的接口。每个接口都定义了需要Listener实现的方法,这些接口决定了Listener对Source的时间做何反应。
  3. Adapter。Adapter类(以”Adapter“结尾)是已经实现所有方法的特殊接口。通常使用Adapter的目的是为了方便。

事件处理机制:

在Java的事件处理的过程中,主要涉及三类对象:

  1. Event:事件,用户对界面操作在Java语言上的描述,以类的形式出现,例如键盘操作对应的事件类是KeyEvent。
  2. Event Source:事件源,事件发生的场所,通常就是各个组件,例如按钮Button
  3. Event handler:事件处理者,接收事件并对其进行处理的对象。

使用委任事件模型进行事件处理,一般通过以下三个步骤来接受或管理事件。

  1. 让类声明所需要的监视器
  2. 为组件(事件源)登记接口
  3. 在类中实现接口中声明的事件处理方法

事件处理举例:P189 的例8.6

第九章

多线程的概念:

(更好的利用CPU)

进程和线程:

进程就是在计算机中正在执行的程序(即处于活动状态的程序),每一个进程都有自己独立的一块内存空间和一组系统资源,如在Windows、Linux等操作系统中可以同时执行多个程序,这里的每一个运行的程序都是一个进程,这些程序使用的内存空间和系统资源都是独立的,并且每个程序也是为了各自的任务而运行,互不干扰。

线程和进程有很多相似的特征,线程可以被看做是进程的进一步细分,也就是把进程完成的任务划分成一个个更小的子任务,每一个子任务就是一个线程,然后用细分的这些线程分别去执行。线程数基于进程的一个基本运行单位,线程同样包括一个内存入口点地址、一个出口点地址。线程是基于进程的一个基本运行单位,线程同样包括一个内存入口点地址、一个出口点地址及能够顺序执行的代码序列。但是线程与进程的重要区别在于线程不能够单独执行,它必须运行在处于活动状态的进程中,线程本身的数据通常只有微处理器的寄存器数据及一个供程序执行时使用的堆栈,因此可以定义线程是程序内部的顺序代码流,也就是说线程是在进程作用域内活动的一系列指令流,所以线程也被称为轻型进程。

多线程简介:

多线程数这样一个机制,它允许在程序中“并行”执行多个指令流,每个指令流被称做一个线程,彼此间的执行互相独立。(线程与线程之间并不一定是相互独立,极有可能是相互影响)

多线程需要操作系统的支持,WIN32平台支持多线程程序,允许程序中存在多个线程。在单CPU计算机系统中,系统把CPU的时间片按照调度算法分配给各个线程,因此各线程实际上是分时执行的,而在多CPU多计算机系统中,同一个程序的不同线程可以分配到不同的CPU上去执行。多个线程的执行是并发的,也就是在逻辑上“同时”,而不是物理上的“同时”。多线程和传统的单线程在程序设计上最大的区别是,各个线程之间的代码是乱序执行的。所以在进行多线程程序设计时,往往会增加一些线程状态控制的语句以使线程的运行满足程序的要求。

Java中的多线程机制:

Java语言都提供了多任务并发执行的能力,Java语言将线程支持与语言运行环境结合在一起。

一个线程是由三部分组成:

  1. 虚拟处理机,封装在java.lang.Thread类中,它控制着整个线程的运行,提供对多线程的支持;
  2. 执行的程序代码,传递给Thread类,由Thread类控制顺序执行;
  3. 程序所处理的数据,传递给Thread类。程序所处理的数据是指在代码执行过程中所要处理的数据。

在Java程序设计中,所有进程都是包含线程概念的,一般都是把主程序当作主线程。可以把一个线程或执行环境想象成一个具有程序代码和虚拟CPU的封装体,每新建一个线程则产生一个对应的封装体,这也使得Java具有了从根本上支持多线程的能力。虚拟CPU包含在Thread类的对象中,创建一个Thread类的对象也就是产生了一个新的线程。当调用构造方法时则通过其参数把虚拟CPU传递给这个新线程,于是,虚拟CPU就将执行这些程序代码,其数据也就得到了处理。

其间,程序代码可以根据需要被多个线程所共享,它们是和数据相互独立的,两个线程在执行同一个类的实例代码时可以共享同一段代码。同理,数据也可以根据需要被多个线程所共享,与代码相互独立,两个线程在访问同一个对象时也可以共享相同的数据。

    在Java编程中,虚拟CPU被封装在Thread线程类的实例之中。这样一来,有多少个需要完成的子任务(线程)就有多少个虚拟CPU这样的“虚拟计算机”在同时运行,把一个较大的任务分割成许多较小的子任务分别地、“同时”地去完成,这就是Java多线程机制。

Java的线程是通过java.lang包中定义的Thread类来实现的。当生成一个Thread类的对象之后,就产生了一个线程,通过该对象实例,可以启动线程、终止线程或者暂时挂起线程等。由于Java在语言级提供了对线程的支持,所以在Java语言中使用多线程要远比在其他语言中使用线程简单的多。

线程类:

通常在Java程序设计中,任何机制都是基于类的,当然线程也不例外,线程的类是Thread类。

线程对象实例表示Java程序中的真正的线程,通过它可以启动线程、终止线程、挂起线程等操作,Thread类是负责向其他类提供线程支持的最主要的类,Thread类在java.lang包中定义,它的构造方法为:public Thread(ThreadGroup group,Runnable target,String name); (其中每个参数都可以为空)

Thread类中的许多有用的方法:

  1. public static void yield(); // 引起当前执行程序暂停,允许其他线程执行。
  2. public static void sleep(long millis);//使当前线程睡眠 millis毫秒

还有什么start,stop,wait,run的话如果这个线程实例是使用实现了Runnable接口的类的实例创建的。

线程的创建:

在Java中,每个程序至少自动拥有一个线程,称为主线程,当程序加载到内存时,启动主线程,如果需要使用其他线程,则可以采用以下两种方式创建新的线程:一种是继承java.lang.Thread类,用它覆盖Thread类的run()方法;另一种是编写一个类,使之实现java.lang.Runnable接口,然后在Thread构造函数中使用它。

  1. 扩展Thread类

四个步骤:

  1. 扩展java.lang.Thread的类;
  2. 用希望的执行代码来实现run()方法;
  3. 通过new关键字实例化该类的一个新对象(即一个线程);
  4. 通过调用start()方法启动线程;

例如:

public class yourThread extends Thread

{
public void run()

{

//需要以线程方式运行的代码,也就是所希望的执行代码

}

}

上面的代码完成了扩展Thread类和重写run()的方法,为了在程序中使用线程,还需要创建一个对象并调用run()方法,如:

yourThread to = new yourThread();

tt.start();

  在这里,start()方法将自动调用在线程体内重写的run()方法来执行线程的具体处理,当run()方法执行完毕时,线程将自动结束。

如例9.1

  1. 实现Runnable

利用Runnable接口创建和运行线程的编程步骤为:

第一步:定义一个Runnable接口的实现类,如MyThread,其内必须实现Runnable接口所声明的run()方法。定义Runnable接口的方法如下:

public class yourThread implements Runnable

{

public void run()

{

…//需要以线程方式运行的代码

}

}

第二步:创建一个Thread类的对象,即创建一个新线程,并用Runnable接口或者Thread类的引用变量指向它,调用Thread类带Runnable引用作为形参的构造方法,把Runnable接口实现类对象传递给Thread类的对象即传递给新线程,为新线程提供程序代码和数据,如:

yourThread yourt = new yourThread();

Thread tt = new Thread(yourt);

第三步:用线程对象调用start()方法启动线程,如:

tt.start();

定义一个实现了Runnable接口的类,将该类的对象作为Thread类的构造方法的参数,生成的Thread对象即为想要创建的线程,这样的线程同样通过start()方法启动。

例9.2

综上,可以看出构造线程体的两种方法各自的优缺点分析如下:

(1)使用Runnable接口

1、可以将CPU、代码和数据分开,形成清晰的模型

2、可以从其他类继承,当一个线程已继承了另一个类时,就只能用实现Runnable接口的方法来创建线程;

3、便于保持程序风格的一致性。

(2)扩展Thread类

1、不能再从其他类继承,适用于单继承线程情况;

2、编写简单,可以直接操作线程。

线程的状态与控制

无论采用扩展Thread类还是实现Runnable接口的方法来实现应用程序的多线程能力,都需要在该类中定义用于完成实际功能的run()方法,这个run()方法称为线程体。按照线程体在计算机系统内存中的状态,可以将线程从产生到灭亡分为新建、就绪、运行、挂起、死亡5种状态

  1. 新建状态

在利用new关键字创建但没执行这段时间

  1. 就绪状态

在处于创建状态的线程中调用start()方法将线程的状态转换为就绪状态。

  1. 运行状态

运行状态表面程序正在运行,该线程已经拥有了对CPU的控制权。

处在运行状态的线程在下列情况下将让出CPU的控制权。

  1. 线程运行完毕
  2. 有比当前进程优先级更高的线程进入可运行状态
  3. 线程主动睡眠一段时间
  4. 线程在等待某一资源
  1. 挂起状态

因等待资源或消息而被挂起的线程则需要由一个外来事件来唤醒。

  1. 死亡状态

正常情况下run()返回使得线程死亡,调用stop()或destroy()亦有同样效果,但是不被推荐,因为前者会产生异常,后者是强制终止,不会释放内存。

线程调用的意义在于JVM应对运行的多个线程进行系统级的协调,以避免多个线程争用有限资源而导致应用系统死机或者崩溃。

Java定义了线程的优先级策略,1-10级,数字越大表明线程的优先级越高。Thread类中定义了表示线程最低,最高和普通优先级的成员变量MIN_PRIORITYMAX_PRIORITY和NORMAL_PRIORITY,代表的优先级等级分别为1、10、5.当一个线程对象被创建时,其默认的线程优先级是5。

线程的同步

线程同步的概念:

由于同一线程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问,这套机制就是线程同步。

线程同步是指Java避免多个线程同时访问一个数据而造成数据混乱的方法。它可以避免多个线程同时访问相同的数据时,产生线程之间的争抢,避免一个线程刚生成的数据又会被其他线程生成的数据所覆盖。

Java用监听器手段来完成线程的同步。

Java使用关键字synchronized来实现多线程的同步,线程同步有两种实现方法,一种是方法同步,另一种是对象同步。

方法同步:

一个类中任何方法都可以设计成为synchronized方法,以防止多线程数据崩溃。当一个线程进入synchronized方法后,能保证在其他任何线程访问这个方法之前完成自己的一次执行。如果一个线程试图访问一个已经启动的synchronized方法;则这个线程必须等待,直到已启动线程执行完毕,释放这个synchronized方法后才能访问。

通过在方法声明中加入synchronized关键字来声明synchronized方法:

public synchronized void methodName([parameterList])

{

}

P221页例9.4

对象同步:

synchronized关键字除了可以放在方法声明中表示整个方法为同步方法外,还可以放在对象前面限制一段代码,当某个对象用synchronized修饰时,表明该对象在任何一个时刻都只能由一个线程访问,例如:

synchronized(object)

{

//允许访问控制的代码

}

方法同步和对象同步的代码是可以相互等价转换的,例如:

public synchronized void yourMethod(){ // … }

public void yourMethod()

{

synchronized(this)

{

// …

}

}

同步方法的缺点

同步机制虽然很方便,但可能导致死锁。死锁是指发生在线程之间相互阻塞的现象,这种现象导致同步线程相互等待,以致每个线程都不能往下执行。在这种情况下, 多个线程都在等待对方完成某个操作,从而导致死锁现象。

线程组

线程组是包括了许多线程的对象渠,线程组拥有一个名字以及与它相关的一些属性,可以用于作为一个组来管理其中的线程。线程组能够有效组织JVM的线程,并且可以提供一些组间的安全性。

线程之间的通信

多线程一个重要特点是它们之间可以互相通信,线程通信使线程之间可以相互交流和等待,可以通过经常分享的数据使线程相互交流,也可以通过线程控制方法使线程相互的等待。Object类为此提供了3个方法:wait()、notify()和notifyAll()。

第十章和第十一章,看一遍就好了,估计不怎么考。

  • 数据库编程 (考一个大题)

用Java来开发数据库前台,通过JDBC技术,可以一致性地访问这些不同的数据库,这样,就可以为不同平台的不同数据库编写一套程序,其优越性是显而易见的。

JDBC技术简介

JDBC概述:JDBC(Java DataBase Connectivity,Java数据库连接),是一套允许Java与SQL数据库对话的程序设计接口,它是用于执行SQL语句的Java API,是Java应用程序连接数据库、存取数据的一种机制,可以为多种关系数据库提供统一的访问,它由一组用Java语言编写的类和接口组成。

由于Java语言具有跨平台性,所以将Java和JDBC结合起来将使程序员只需写一次程序就可让它在任何平台上运行,这也进一步体现了Java语言的“编写一次,到处运行”的宗旨,真正实现其跨平台性。

主要完成以下四方面的工作,(1)加载JDBC驱动程序;(2)建立与数据库的连接;(3)使用SQL语句进行数据库操作并处理结果;(4)关闭相关连接。

JDBC接口与驱动程序

JDBC主要提供两个层次的接口,分别是面向程序开发人员的JDBC API和面向底层的JDBC Driver API,它们的功能如图12.2所示。 P285

JDBC API
JDBC API被描述成一组抽象的接口,JDBC的接口和类定义都在java.sql包中,利用这些接口和类可以使应用程序很容易地打开某个数据库连接、执行SQL语句、并且处理结果。下面对这些类和接口提供的方法进行详细介绍。


1、java.sql.DriverManager

java.sql.DriverManager用来装载驱动程序、并为创建新的数据连接提供支持。

JDBC的DriverManager如同一座桥梁,一方面,它面向程序提供一个统一的连接数据库的接口;另一方面,它管理JDBC驱动程序,DriverManager类就是这个管理层。下面是Driver Manager类提供的主要方法。

  1. getDriver(String url):根据指定url定位一个驱动。
  2. getDrivers():获得当前调用访问的所有加载的JDBC驱动。
  3. get Connection():使用给定的url建立一个数据库连接,并返回一个Connection接口对象(主要用这个)。

  1. java.sql.Connection接口

Connection接口用于一个特定的数据库连接,它包含维持该连接的所有信息,并提供关于这个连接的方法。

  1. create Statement():在本连接上生成一个Statement对象,该对象可对本连接的特定数据库发送SQL语句。
  2. close():关闭当前的JDBC数据库连接。
  1. java.sql.Statement接口

java.sql.Statement在一个给定的连接中作为SQL执行声明,它包含了两个重要的子类java.sql.PreparedStatement(用于执行预编译的SQL声明)和java.sql.CallableStatement(用于执行数据库中的存储过程)。

Statement对象表示用结构化查询语言编写的数据库查询,用于将SQL语句发送到数据库中。Statement对象本身并不包含SQL语句,因而必须给查询方法提供SQL语句作为参数。下面是Statement接口声明的主要方法。

  1. executeQuery(String sql):执行一条SQL插入语句,返回查询结果对象。
  2. executeUpdate(String sql):执行一条SQL插入、更新、删除语句,返回操作影响的行数
  3. execute(String sql):执行一条SQL语句。
  1. java.sql.ResultSet接口

java.sql.ResultSet用于保存数据库结果集,通常由执行查询数据库的语句生成。

java.sql.ResultSet对于给定声明获得结果的存取控制。在这些接口中提供了非常丰富的方法,可以使用这种方法对数据库进行各种操作。

JDBC Drive API

它是面向驱动程序开发的编程接口。常见的JDBC驱动程序主要有四种类型,它们分别是:

  1. JDBC-ODBC桥加ODBC驱动程序(JDBC-ODBC bridge plus ODBC driver)

JDBC-ODBC桥驱动程序,将JDBC调用转换为ODBC的调用。JDBC-ODBC桥包含在Sun公司提供的JDBC软件包中,它是一种JDBC驱动程序,在ODBC的基础上实现了JDBC功能,它充分发挥了支持ODBC大量数据源的优势。JDBC利用JDBC-ODBC桥,通过ODBC来存取数据,JDBC调用被传入JDBC-ODBC桥,然后通过ODBC调用适当的ODBC驱动程序,以实现最终的数据存储。因此,这种类型的驱动程序适用于局域网中或者用于三层体系结构中。JDBC-ODBC桥驱动程序可以使JDBC访问几乎所有类型的数据库。

  1. 本地API、部分是Java的驱动程序

该类型的驱动程序用于将JDBC的调用转换成主流数据库API的本机调用。和第一种JDBC驱动程序类似,这类的驱动程序也需要在每一个客户机安装数据库系统的客户端,因而适用于局域网中。

  1. JDBC-Net的纯Java驱动程序(JDBC- Net pure Java driver)

该类型的驱动程序用于将JDBC的调用转换成与数据库无关的网络访问协议,利用中间件将客户端连接到不同类型的数据库系统。使用这种驱动程序不需要在客户端安装其他软件、并且能访问多种数据库。这种驱动程序是与平台无关的,并且与用户访问的数据库系统无关,特别适合组建三层的应用模型,这是最为灵活的JDBC驱动系统。

  1. 本地协议的纯Java驱动程序(Native-protocol pure Java driver)

这种类型的驱动程序将JDBC调用直接转化为某种特定数据库的专用的网络访问协议,可以直接从客户机来访问数据库系统。这种驱动程序与平台无关,而与特定的数据库有关,这类驱动程序一般由数据库厂商提供,

第3、4两类都是纯Java的驱动程序,它们具有Java的所有优点,因此,对于Java开发者来说,它们在性能、可移植性、功能等方面都有优势。

建立与数据库等连接

建立JDBC-ODBC桥接器用“ Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);”语句,其中Class是java.lang包中的一个类,该类通过调用它的方法forName就可以建立JDBC-ODBC桥接器,建立桥接器可能发生异常,捕获这个异常的方法如下:

try{

Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

}catch(ClassNotFoundException e)

{}

桥接器建好后,就要将Java与数据库真正建立连接了。使用java..sql包中的Connection类声明一个连接对象,再使用类DriverManager的方法getConnection创建这个连接对象,语句格式如下:

Connection conn;

conn = DriverManager.getConnection(“jdbc:odbc:数据源名”,”password”);

这样,Java程序就与数据库真正建立了连接。若连接成功,则返回一个Connection类的对象conn,以后对这个数据源的操作都是基于conn对象的。

执行查询语句

JDBC一般采用基于Statement对象的查询方法。首先使用Statement类声明一个SQL语句对象,然后通过该连接对象调用createStatement()方法创建SQL语句对象。语句格式为:

Statement sql;

sql = conn.createStatement();

有了SQL对象后,这个对象就可以调用相应的方法实现对数据库的查询操作。具体地,在Statement对象上,可以使用execQuery()方法执行查询语句。execQuery()方法的参数是一个String对象,即一个SQL的数据处理语句,并将查询结果放在一个ResultSet类声明的对象中,然后进行对应的处理,例如:

ResultSet rs = sql.execQuery(“Select * From TableName”);

在SQL中查询操作是通过select语句来完成的,基本的select语句格式如下:

select<列名>from<表名>

假设有一个名为stu的表,里面包含id、name、sex、score几个字段,那么如果要查询表中name字段列的所有数据可以使用下面的命令:

select name from stu

如果要查询表中的所有数据,可以使用下面的命令:

select * from stu

这是一条最简单的select语句,可以把它分为三部分:select、*和from stu,三部分之间用空格隔开。其中select为SQL语言的保留字,是任何查询的第一个命令:“*”所处的位置上的参数是用来限定要返回的字段的,“*”表示返回表中所有的字段:from是保留字,它表示从哪个数据库表中得到数据,在该例中,是从stu表中查找数据。

使用select语句除了实现上述简单功能外,还可以利用select语句提供的各种子句进行更高级的查询功能,具体可实现的查询功能如下:

  1. 筛选查询

利用select的where子句可以实现对表的查询结果进行筛选,其格式为:

select<字段名1>[字段名2,…]from<表名>where<条件>

  1. 排序查询

select<字段名1>[字段2,…]from<表名>order by<字段名>;

  1. 模糊查询

select<字段名>[字段名2,…]from<表名>where<字段名>like<查询条件>

对数据库进行更新操作

采用DML语句对数据库记录进行、修改和删除操作,分别对应于SQL的INSERT、UPDATE和DELETE语句。下面将对该类操作语句进行简单的介绍:

  1. 插入记录(INSERT)

使用SQL语句的INSERT命令可以向数据库中插入记录,INSERT命令的基本形式为:

INSERT INTO 表名 [(字段名1,字段名2,] VALUES(值1,值2,…)

  1. 更新记录(UPDATE)

使用UPDATE命令可以对数据库中符合条件的记录进行修改。Update命令的格式如下:

UPDATE<表名>SET 字段1 = 值 1[,字段2 = 值2] WHERE <条件>
3、 删除记录(DELETE)

对数据库进行删除操作使用的是DELETE命令,DELETE语句有两种,即带条件的DELETE语句和不带条件的DELETE语句。DELETE语句的格式如下:

DELETE FROM <表名> [WHERE 条件]

事务

事务由一个或多个语句组成:这些语句已被执行、完成并提交或还原。当调用方法commit()或rollback()时,当前事物即告结束,另一个事务随即开始。默许情况下,新连接将处于自动提交模式,也就是说,当执行完语句后,将自动对那个语句调用commit()方法。这种情况下,由于每个语句都是被单独提交的,因此一个事务只由一个语句组成。如果禁用自动提交模式,事务将要等到commit()或rollback()方法被显式调用才结束,因此它将包括上一次调用commit()或rollback()方法以来所有执行过的语句。对于第二种情况,事务红的所有语句将作为组来提交或还原。

P298例题12.2要看

  • 输入/输出流编程

File类应用举例

文件操作是程序设计必不可少的部分。计算机把需要长期保存的数据以文件的形式存放在各种外部存储设备上。在需要输入数据时,从文件读出数据;而需要输出数据时,把数据写入文件。

File类用来获取文件或目录的信息

File类提供方法用以访问如路径、名称、大小、日期、读写属性等文件或目录的信息,也可以创建文件、删除文件、改变文件名、创建目录等。Java把目录看成特殊的文件,作为文件名的列表处理。File类的直接父类是Object。

File类的构造方法

public File(String pathname)

public File(File parent,String child)

Public FileString parent,String child)

文件的处理

文件输入/输出流类FileInputStream和FileOutputStream提供了对文件顺序读/写的方法。文件输入流类FileInputStream用于读取文件中的字节数据,其直接父类为InputStream;文件输出流类FileOutStream用于向文件写入字节数据,其直接父类为OutputStream。

  1. FileInputStream类的构造方法

public FileInputStream(String name);

File file

FileDescriptor fd

  1. FileOutputStream类的构造方法

同上

  1. FileInputStream类的成员方法

FileInputStream类中的成员方法被调用时会产生IOException异常,如P312

  1. FileOutputStream类的成员方法

同上

Reader与Writer类应用举例

P313                                 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java程序设计项目教程 第二版》是一本专门针对Java程序设计项目的教材。这本教材内容详实,适合初学者和有一定基础的读者。下面我将从几个方面介绍这本教材。 首先,该教材的内容极其全面和细致。书中从基本的Java语法和面向对象编程的概念讲起,逐步引导读者学习如何设计和实现Java程序项目。同时,该教材也涉及了一些常用的Java类库和开发工具的使用方法,如Swing GUI、JavaFX、数据库访问等。无论是学习Java的基础知识,还是进一步提高自己的项目开发技巧,都可以在此书中找到所需知识。 其次,该教材注重实践和项目案例。课本中不仅提供了丰富的练习题,还通过一系列实际项目案例来让读者应用所学知识解决实际问题。这种实践性的学习方法有助于读者从理论知识到实际应用的过渡,培养实际项目开发的能力。 另外,教材的编写风格简洁明了。作者通过清晰的语言和简单直观的示例代码,将复杂的概念和语法讲解得易于理解和掌握。这对于初学者来说非常友好,能够帮助他们快速入门并提高编程水平。 总结而言,《Java程序设计项目教程 第二版》是一本很好的Java项目编程教材。它内容全面,重点实践,在编写风格简洁明了。读者通过学习这本教材,不仅可以掌握Java语言基础,还能够应用所学知识开发项目。无论是初学者还是有一定基础的读者,都可以从中获得实际的帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值