当前位置:网站首页 > Java基础 > 正文

java技术基础



JAVA技术教程(基础篇)

说明:JAVA语言是随着网络的不断发展而产生的一种计算机高级语

言,它具备优越的安全性、可移植性等。阐述过程中,对语言的普遍

意义上的内容将不做重点介绍,如JAVA的数据类型、语法等。另外,

由于JAVA语言是一种面向对象的,对于面向对象的理论讲解也将不

作为重点,而讲述面向对象在JAVA中的实现。对JAVA根据实际的

需要,将重点阐述APPLET技术、线程技术,对于AWT、JAVA高级

网络技术如JSP、JDBC等内容将作为介绍性内容。

第一部分JAVA程序介绍

1、程序类型:

Application应用程序和Applet小应用程序

i.Application应用程序与C++一样,是完全独立开发和应用的

程序(关于JAVA与C及C++的具体区别在后面将做详细介

绍)。

ii.Applet小应用程序是JAVA实现与Internet交互的、能够实现

网络特性的应用程序。其必须嵌入Html中实现程序的运行,

不能独立运行。

2、JAVA程序结构:

JAVA的程序结构包括四部分:原代码.java,类文件.class,

文件归档工具jar生成的.jar和存储对象状态的序列文件.ser

原代码JAVA的文件结构如下:

package(0or1)

import(0orserveral)

//JAVA默认状态为java.lang,object包,所以在简单的程序

过程中可以不用引入包。

publicclassDefinition(0or1)

classDefinition(0orserveral)

interfaceDefinition(0orserveral)

3、程序实例:

Java程序的开发过程:

1.Application:应用程序的开发

•编辑你的程序文件,存为纯文本文件javaApp.java,后

缀必须为java

(可以通过任意的文本编辑工具写入程序代码,后缀名

为java)

例1

classjavaApp

(

publicstaticvoidmain(Stringargs[])

(

System.out.println("这是我的第一个Java

Application!");

)

)

•编译成类class文件:javacjavaApp.java

•执行程序:javajavaApp

•main方法中的参数同样如C及C++中一样能够传递参

注意:

用javac和java编译、执行源、类文件的时javac编译必须

带后缀.java;java执行类文件不带.class后缀;文件名大小

写必须一致。且文件名必须Application程序入口类(唯一

含main方法的类)名称一致。如果Java源文件的文件名

不是入口类的名称,编译后产生的类文件依然会是与入口

类名相同的名称。

上述程序中首先用保留字class来声明一个新的类,其类

名为javaApp,它是一个公共类(public)。整个类定义由

大括号{}括起来。在该类中定义了一个main()方法,

其中public表示访问权限,指明所有的类都可以使用这一

方法;static指明该方法是一个类方法,它可以通过类名

直接调用;void则指明main()方法不返回任何值。对于

一个应用程序来说,main()方法是必须的,而且必须按照

如上的格式来定义。Java解释器在没有生成任何实例的情

况下,以main()作为入口来执行程序。Java程序中可以

定义多个类,每个类中可以定义多个方法,但是最多只能

有一个公共类,main()方法也只能有一个,作为程序的入

口。main()方法定义中,括号()中的Stringargs[]是

传递给main()方法的参数,参数名为args,它是类String

的一个实例,参数可以为。个或多个,每个参数用“类名

参数名”来指定,多个参数间用逗号分隔。

现在我们可以运行该程序。首先把它放到一个名为

javaApp.java的文件中,这里,文件名应和类名相同,因

为Java解释器要求公共类必须放在与其同名的文件中。然

后对它进行编译:

C:>编译器路径javacJavaApp.java

编译的结果是生成字节码文件javaApp.classo最后用

java解释器来运行该字节码文件:

C:>javajavaApp

2.Applet:小应用程序的开发

•同上,也需要编译为class文件,源文件javaApplet.java

如下:

例2:

importjava.awt.*;

publicclassjavaAppletextendsjava.applet.Applet

(

publicvoidpaint(Graphicsg)

(

g.drawString("这是我的第一个Java

Applet!",40,20);

)

)

•生成HTML文件first.html,含上面的java类:

<html>

<body>

<center>

<hl>下面的文字是用Java输出的!</hl>

</center>

<appletcode="javaApplet.class"width=400height=300>

</applet>

</body>

</html>

•用浏览器或java的浏览器运行:

appletviewerfirst.html

注意:

a)在Html嵌入的是Java原程序经过编译后生成的

Class文件;

b)Html中applet标记含有很多参数针对如何调用

applet,其中重要的有:code=(applet文件

名),codebase=(代码基址,是包含着applet代码的目

录。在没有给出时,默认为当前html文档的地址)、

<paramname=参数名value=参数值>。

例2这是一个简单的Applet(小应用程序)。程序中,首

先用import语句输入java,awt下所有的包,使得该程

序可能使用这些包中所定义的类,它类似于C中的

#include语句。然后声明一个公共类javaApplet,用

extends指明它是Applet的子类。在类中,我们重写父

类Applet的paint()方法,其中参数g为Graphics类,

它表明当前作画的上下文。在paint()方法中,调用g

的方法drawString(),在坐标处输出字符串““这是我

的第一个JavaApplet!”,其中坐标是用象素点来表示

的。

这个程序中没有实现main()方法,这是Applet与应用

程序Application(如例1)的区别之一。为了运行该

程序,首先我们也要把它放在文件javaApplet.java中,

然后对它进行编译:

C:>javacjavaApplet.java

得到字节码文件javaApplet.class。由于Applet中没

有main()方法作为Java解释器的入口,我们必须编写

HTML文件,把该Applet嵌入其中,然后用appletviewer

来运行,或在支持Java的浏览器上运行。它的文件如

下:

<HTML>

<HEAD>

<TITLE>AnApplet</TITLE>

</HEAD>

<BODY>

<appIetcode="javaAppIet.cIass“width=200

height=40>

</appIet>

</BODY>

</HTML>

其中用〈Applet)标记来启动javaApplet,code指明字

节码所在的文件,width和height指明applet所占的

大小,我们把这个HTML文件存入Example.html,然后

运行:

C:>appletviewerExample,html

从上述例子中可以看出,Java程序是由类构成的,对于

一个应用程序来说,必须有一个类中定义main()方法,

而对applet来说,它必须作为Applet一个子类。在类的

定义中,应包含类变量的声明和类中方法的实现。Java

在基本数据类型、运算符、表达式、控制语句等方面与

C、C++基本上是相同的,但它同时也增加了一些新的

内容,在以后的各章中,会详细介绍。本节中,只是使

大家对Java程序有一个初步的了解。

3、Applet和Application的混合程序:

Java类文件有可能既是一个javaapplication又是java

appleto虽然这样的java文件比较复杂,但是它却既可

以在浏览器中运行,又可以单独运行。

实例:

例3:

importjava.applet.Applet;

importjava.awt.*;

importjava.awt.event.*;

publicclassAppletappextendsApplet{

publicstaticvoidmain(Stringargs[]){

Frameframe=newFrame("Application");

//创建一个Frame对象作为装载Applet的环境

Appletappapp=newAppletappO;

frame.add("center",app);

frame.setSize(200,200);

frame.validate();

frame,addWindowListener(new

WindowControl(app));

app.init();

app.start();

)

publicvoidpaint(Graphicsg){

g.drawString("helloappletapplication",25,25);

)

publicvoiddestroy(){

System.exit(O);

)

)

classWindowControlextendsWindowAdapter{

Appletc;

publicWindowControl(Appletc){

this.c=c;

)

publicvoidwindowClosing(WindowEvente){

c.destroy();

)

)

4、Java程序开发平台的介绍:

开发Java程序一般使用的平台主要有:JDK、Jbuild、VJ++等。

其中主要介绍JDK、Jbuild。

二、面向对象程序设计

关于JAVA中面向对象的程序设计概念,由于在《面向对象程序设计

和C++实践》中,已经进行了详细的解释。所以,在此关于JAVA中

面向对象的知识将重点介绍以下内容,其余部分将在具体程序事例中

讲述。

1、接口:

a)接口产生的意义:由于JAVA只允许单重继承性,即每个Java

中的类只能有一个父类(但一个父类可以有多个子类)。多重

继承增加了编程的复杂性,但提高了编程的功能。Java为了弥

补由于单继承性而带来程序功能降低的缺陷,特别是在我们创

建的类的行为在类层次的不同分支中已有定义的情况,就提出

接口的概念。在某种程度上,接口具有这类的特性。

b)接口的定义:接口就是一种没有完全实现的类,包含抽象的方

法和常量定义。接口中不能有方法实现的具体代码。接口就是

抽象的类。定义接口使用interface关键字。

erfacePrintable{

voidprint();

)

classMouseimplementsPrintable{

voidprint(){

System.out.println("Mouse");

)

)

classDuckimplementsPrintable{

voidprint(){

System.out.println(“Duck");

)

)

c)接口的使用:

i.接口的定义和类相似,在很多地方它们同样进行处理,它

们定义在同一个文件中。不同的是接口不需要通过new来

创建它的实体。

ii.接口也是可以相互继承的。

如:interfaceAextendsB{

iii.一个类同时可以实现多个接口。

如:classclass_AinterfaceA_inteface,B_interface....{

iv.在类实现了某个接口后就必须在类中对该接口的抽象方法

具体化即给抽象方法写具体代码。

v.接口可以实现多重继承,既可以通过extends将多个接口组

合成一个接口。但接口不能通过implements实现其它接口。

vi.java类库中也提供了很多接口,Runnable就是其中一个。

(具体可查阅相关资料或开发平台中的帮助,线程的定义

和实现中就是通过某个类实现Runnable接口的)

2、包:

a)包产生的意义:

i.包的使用可以实现一组类和接口的封装,这也正是面向对

象的思想。

ii.由于java编译器以入口类名为文件名生成源文件,这在一

定程度上会造成同名类的冲突,通过java技术基础包可以使在其后定义

的所有类集合在一起,使在不同包中的入口类名相同。

b)包的定义:package关键字定义包。

如:packageFirst_package;

publiclassMyclass{

)

classyourclass{

c)包的引用:

i.一个源文件最多只能有一个包定义,如果有包定义必须出

现在文件的最前头。

ii.包的引用通过关键子importo但对java.lang包(最基本

的语言处理类)不需要import。如,String类就是lang包

中的类。

iii.包与类相似也是有层次的。

如,java类库中顶层是java,下一层有awt、io、net等。

这些包又有下一层,如在awt包中还有image、peer、test

等。在引用这些包时通过.来实现其层次性。如要引用

image包,格式为:java.awt.image。另外,如在程序中需

要用到某个包中许多子包的类时则可以通过*来实现多

个包的引用。

如java.awt.*

则表示可以引用awt包中子包的类。

但通过*来引用包并没有引用包中其他包的public类,如

要引用java.awt.image包中的ImageFilter类则必须单独

使用import语句。

如:importjava.awt.*;

importjava.awt.image.*;〃或者import

java.awt.image.ImageFilter;

也可以在程序中引用一个类的时候加上包名,这样不需

要使用import语句:java.awt.image.ImageFilterimf;如果

一个程序中引用了多个包,而且有两个及更多的包中有

相同的方法,则必须在具体用到该方法时必须指明该方

法所属的包。

iv、java中提供的基本包类。

•java.lang最基本的语言处理类;

•java.io实现输入输出

•java.util;包含一些如特殊类;

•用于实现网络连接,与java.io合用实现对

网络文档的读写;

•java.applet用于创建可在支持java的浏览器中运

行的javaApplet;

•java.awt可创建平台独立的图形用户接口(GUI)

程序

3、内部类(InnerClass):

a)内部类产生的意义:

Java中不允许实现类的多重继承,但当一个类需要实现多个类

中方法时,我们可以选择通过实现接口来达到这样的目的。但

在实现接口时必须实现该接口中所有的方法,这样有时会很烦

琐,故此Java中就增加了一个新的概念:内部类(InnerClass)。

在JDK1.1版以后就支持了内部类(InnerClass)o比如:在用

到AWT编程过程中,在需要处理多个事件时(如鼠标的点击

事件就有左、右、中等几种方法)就需要一个类能够使用多个

事件适配器类的方法,根据Java中不能实现多重继承的特性,

只能实现这些事件的监听器接口,但接口又要求必须实现其中

所有的方法,这样又很烦琐。

b)内部类的定义:

内部类就是嵌套在类中的类。

c)内部类的特性:

i.InnerClass一般用在定义它的类或语句块之内,在外部引

用它时必须给出完整的名称。InnerClass名字不能与包含

它的类名相同。

ii.InnerClass可以使用包含它的类的静态和实例成员变量,

也可以使用它所在方法的局部变量。

iii.InnerClass可以定义为Abstract的。

iv.InnerClass可以声明为private或protectedo

v.InnerClass若声明为static,就变成了顶层类,就不能使用局

部变量。

vi.InnerClass中的成员不能声明为static,只有在顶层类中才

能声明static成员。如果想在InnerClass中声明任何static

成员,则该InnerClass必须声明为static。

vii.建立内部类的对象:

1、在外部类的实例成员方法中可以直接建立内部类的

对象,不能在类方法中建立。

2、在外部类的类(static)成员方法中,以及与外部类

并行的其他类中的方法中,建立内部类对象必须与外

部类关联。outer.inner

viii.内部类的使用周期;

内部类定义在一个具体的语句块中,内部类只能在该语句

块的生命周期内存取该语句块中的局部变量。

d)事例:

importjava.awt.*;

importjava.awt.event.*;

publicclassTwoListenInner{

privateFrame;

privateTextFieldtf;

publicstaticvoidmian(Stringargs[]){

TwoLisenlnnerthat=newTwoLisenInner();

That.goQ;

)

publicvoidgo(){

f=newFrame(t4TwoListenerexample");

f.add("North”,newLabel(uClickanddragthemouse^^));

tf=newTextField(30);

f.addMouseMotionListener(newMouseMotionHandler());

f.addMouseListener(newMouseEventHandler());

f.setSize(3OO,3OO);

f.setVisible(true);

)

publicclassMouseMotionHandlerextendsMouseMotionAdapter{

publicvoidmouseDragged(MouseEvente){

Strings="Mousedragging:X="+e.getX0+“Y="+e,getY();

tf.setText(s);

)

)

publicclassMouseEventHandlerextendsMouseAdapter{

publicvoidmouseEntered(MouseEvente){

Strings="themouseEntered^^;

tf.setText(s);

)

publicvoidmouseExited(MouseEvente){

Strings="themousehasleftthebuilding^^;

tf.setText(s);

)

)

e)与内部类相关的概念还有内部接口和内部抽象类,其使用和概

念与内部类几乎一致,在此不赘述!

4、Java与C/C++的比较:

Java使用了类似于C/C++的语法,而去除了C/C++的许多不合

理的内容,以实现其简单、鲁棒、安全性等特性。

a)全局变量

Java中不能定义全局变量,只能通过类中的公用、静态的变量

实现全局变量。这样便保证了更好的安全性,全局变量被封装

在类中。而C/C++中,依赖于不加封装的全局变量常造成系统

的崩溃。(在引用类中私有变量和公用变量时,造成变量名称

的混乱,从而造成系统内存的错误)

b)无条件转移指令

与C/C++不同,Java不支持goto语句,而通过例外处理语句

try、catch、final等来代替C/C++中的goto语句,以处理遇到

错误跳转的情况,使程序更加结构化提高了程序的可读性。

c)指针

指针是C/C++中最灵活,但也是最容易出错的数据类型。以指

针进行内存操作常造成不可预知的错误。而且,通过指针对内

存进行显示类型转换后,可以访问类的私有变量,破坏了安全

性。Java中,程序员不能进行任何指针操作,同时一,数组在java

中用类来实现很好地解决了数组越界这个C/C++中不作检查

的错误。

d)内存管理

C中,程序员使用库函数malloc()和free()来分配和释放内存,

C++中则是运算符new和delete。再次释放已释放的内存块或

释放未分配的内存块,会造成系统的崩溃,而忘记释放不再使

用的内存块也会逐渐耗尽系统资源。在Java中,所有的数据

结构都是对象,通过运算符new分配内存并得到对象的使用

权,而实际上分配给对象的内存可随程序运行而改变。Java

自动进行管理并进行自动垃圾收集。有效的防止了因程序员误

操作而造成的错误,并更好的利用了系统资源。

e)数据类型的一致性

在C/C++中,不同平台上,编译器对简单的数据类型如int、

float等分别分配了不同的字节数。例如,int在IBMPC上为

16位,在VAX」1上为32位,因此导致了代码的不可一移植。

而在Java中,对某种数据类型总是分配固定的位数,这就保

证了Java的平台无关性和可移植性。

f)类型转换

在C/C++中,可以通过指针进行任意的类型转换,导致不安全

的可能性存在。在Java中,系统要对对象的处理进行相容性

的检查,防止不安全的转换。

g)头文件

在C/C++中使用头文件声明类的原型和全局变量及库函数等。

大的系统中,维护这些头文件非常困难。Java不支持头文件,

类成员的类型和访问权限封装在一个类中,运行时系统对此访

问进行控制。防止对私有成员的操作。另外,Java中用import

语句与其他类进行通信,以使用他们的方法。

h)结构和联合

C/C++中的结构和联合的成员均为公有,带来了安全性的问

题。Java不支持结构和联合,所有内容封装在类中。

i)预处理

C/C++中用宏定义实现的代码影响了程序的可读性。Java不支

持宏,以关键字final声明常量。

第八章异常处理

1、概念的产生:

在C/C++这样的语言中,对运行时间错误的处理可以有多种

形式,比如访问了一个无效指针,系统要么退出程序,告诉

你一个错误信息,要么系统死机。如果用函数处理所发生的

错误,必须有一个特定的返回值来通知函数调用者错误的发

生,或使用输出变量来辨认错误。总之,整个对错误的处理

不一致。为了能够有效处理程序运行错误,就必须建立统一

的机制来捕捉、处理异常。JAVA采用的面向对象方法处理

异常则解决了这个问题。

2、Java例外(异常):

eg8.1

importjava.io.*;

classExceptionDemo1{

publicstaticvoidmain(Stringargs[]){

FilelnputStreamfis=newFileInputStream("text");

intb;

while(b=fis.read()!=-1){

System.out.print(b);

)

fis.close();

此事例进行编译时系统将报错。(具体报错参看编译显示)

eg8.2

classExceptionDemo2{

publicstaticvoidmain(Stringargs[]){

inta=0;

System.out.printin(5/a);

)

)

此事例编译时没有报任何错误,但在执行时报错。

上面所举之两个实例,我们所遇到的所谓报错就是Java中所

提的异常(例外)。编译、运行时所报的错误信息显示的内容

java.io.FileNotFoundExceptionJava.io.IOException以及

java.lang.ArithmeticException分别指明了例外的类型。其概念

也正如类的概念。同时,从实例8.1和8.2报出例外的过程可

以看出,有些例外在程序中必须处理,否则编译都不通过

(eg8.1)o而有些例外在程序中可以不做处理,而直接由系统

运行时系统来处理(eg8.2)。

由此,则引出了我们下面将要讨论的例外的处理问题。

3、例外的处理机制:

在Java程序如果在运行中出现了例外就会生成一个例外对象。

这个对象可能是由正在运行的方法生成,也可能是Java虚拟机

生成,其中包括一些信息指明例外事件的类型以及当例外发生

时程序的运行状态等。生成的例外对象将传递给Java运行时系

统,这一例外的产生和提交的过程称为抛弃(throw)例外。

当Java运行时系统得到这个例外对象时,将会寻找处理这个例

外的代码。寻找按照方法的调用栈逐层上升。这个过程称为捕

获(catch)例外。如果捕获不到则程序停止。如8.2。

4、例外类的层次

由于Java处理例外采用了面向对象的思想,则整个例外自然包

含了层次性。这里Java将所有例外类对应于类Throwable及其

子类。具体层次结构见下图:

从上面的图我们看出,Java中的异常事件分为两类。一类继承

于类Error,通常这种例外程序是不应该捕获的例外,也不抛弃

这种例外。另外一类继承Exception的例外则是需要大量处理的

例外。

在Exception类下面的子类中,继承于RuntimeException的类代

表了程序运行时生成的例外。如eg8.2中产生的

ArithmeticException□这种例外比较普遍而且系统自身就能够处

理,所以不用程序员去用代码处理。而其它继承于Exception的

子类则代表非运行是例外。如eg8.1。这种例外程序必须处理。

下面我们将要讨论的例外处理就是针对这部分例外而进行的。

5、例外处理:

异常的处理可以有以下儿种:对运行时异常可以不做处理;使

用try-catch-finally语句捕获异常;通过throws子句声明异常,

还可以定义自己的异常类,并用他throw语句抛出它。

其中,try-catch-finally语句其语法为:

try{

.……〃可能产生例外的代码段

}catch(ExceptionName1e){

......〃捕获异常

}catch(ExceptionName2e){

......〃捕获异常

}finally{

.....〃不管是否有异常必须执行的代码段,一般是处理一些善

后事情

)

另外,如果在一个方法中生成一个例外,但是这个方法并不确

切知道该如何对这个例外进行处理,此时一般就由调用它的这

个方法来处理。这时一个方法就得声明抛弃例外使得例外对象

可以从调用栈向后传播,直到被捕获。声明抛弃例外是在一个

方法声明中的throws子句来指明并由合适的程序代码来处理,

当然也可以不处理。但是,对于非运行状态的例外必须处理:

例如:publicintread()throwsIOException{

)

同时一,我们在捕获一个例外前,例外都是通过throw语句抛出

的。只是抛弃例外可以是自己写的Java代码、JDK中的某个类

或者是Java运行时的系统。一般如果我们自己定义例外,则需

要自己写代码将此例外抛出供程序捕获。注意:用throw语句

抛出例外首先要生成例外对象,并且该例外必须是throwable

类或子类。

例如:lOExceptione=newIOException();〃生成例外对象

throwe;

thrownewString("wanttothrow")由于String并不是

throwable或子类,所以该错误。

eg8.3

importjava.io.*;

classExceptionDemo{

publicstaticvoidmain(Stringargs[])throwslOException{

〃通过throws语句抛弃lOException例外

FilelnputStreamfis=null;

try{〃可能产生例外的代码段

System.out.println("firstarguments"+args[O]);

fis=newFileInputStream("text");

System.out.println("contentoftextis:");

intb;

while((b=fis.read())!=-1){

System.out.println((char)b);

)

}catch(FileNotFoundExceptione){〃捕获例外

System.out.println(e);

}catch(lOExceptione){

System.out.println(e);

}catch(IndexOutOfBoundsExceptione){

System.out.println(e);

}finally{//必须执行的代码段

if(fis!=null){

System.out.println("closingFilelnputStream,

fis.close();

}else{

System.out.println("FileInputStreamnotopen");

注意:1)在try语句中产生例外对象后,系统会将该例外对象沿

调用栈向上寻找相匹配(是指参数类型与例外对象的类型完

全相同或者为其父类)的catch语句。所以,捕获例外的顺

序是和不同catch语句的顺序有关了。因此,在安排catch语

句顺序时必须是从特殊到一般。(如上例中,

FileNotFoundException是lOException的子类)(在下面的例

子中,如果调换两个catch语句的顺序则编译报错)

importjava.io.*;

publicclassQuizl{

publicstaticvoidmain(Stringarg[]){

inti;

System.out.print("GO");

try(

System.out.print("in");

i=System.in.read();

if(i=='0'){thrownewMyException();}

System.out.print("this");

)

catch(IOExceptione){}

catch(MyExceptione){

System.out.print("that");

)

System.out.print("way. ");

)

}

classMyExceptionextendsException{}

运行该程序后输入字符'O',请问运行结果为何?

(A)Gointhisway

(B)Gointhatthisway

(C)Gointhat

(D)Gointhatway

第十二、十三章图形用户界面

通过GUI(GraphicalUserInterface),用户和程序可以友好地进行

交互。Java中的AWT和Swing就包含了很多的类来支持GUI的设

计。AWT的主要功能:用户界面组件、事件处理模型、图形和图象

工具、布局管理器等。

1、生成Java图形用户界面

根据课本图12.2所示,在java.lang.object包之下有很多实现图

形用户界面的包和类,其中,Component类为java.awt包中最核

心的部分。它是构成Java图形用户界面的基础,其他所有组件都

是由这个类派生出来的。Component类是个抽象类(说明?),

不能直接使用。在Component类中,定义了AWT组件所具有的

一般功能(说明?)o

1)基本的绘画支持

方法repaint。、paint。、update。等用来在屏幕上绘制组件。

组件的绘制过程是不能被中断的,AWT绘图系统通过一个单

独的线程来控制程序何时进行组件的绘制。程序中也可以通

过调用repaint。来实现绘画,方法repaint。首先调用update()

进行背景清除,然后由update。调用paint。进行绘图。(在

Applet的动画程序体现)

2)外形控制(字体getFont。,颜色getColorModel等)

3)大小和位置控制

组件大小和位置主要取决组件所处的容器的布局管理器,但

组件本身也能够有自己的方法实现大小、位置的控制。

setSize()>setLocation。等

4)图象处理

类Component实现接口ImageObserver,其中方法

imageUpdate。用来图象跟踪。

5)组件状态控制

可用setEnable()>可视setVisible。、isVisible。返回组件状态等。

6)Container类的功能:

i.组件管理:add。添加组件、remove。删除组件

countComponent()用来统计容器内组件的个数,

getComponent。获得某个组件,paintComponents。绘制

容器内所有组件。

ii.布局管理:每个容器都和一个布局管理器关联。容器

通过setLayout。设置某种布局。

2、容器与组件:

常见的组件类:button、Label等,常用的容器有Frame>Panel、

Applet等o

Java的图形用户界面最基本的部分是组件,组件是以图形化

方式显示在屏幕上,并能够与用户交互。组件不能对显示,

必须将组件放在一定的容器中才能显示。容器实际就是

Component的子类,所以,容器本身也是个组件。

在容器中放置组件安排其位置和大小,必须注意:

1)容器中布局管理器负责组件的大小和位置,用户无法在

有直接通过程序的方法setLocation()>setSize。等来改

变,这样都会被布局管理器覆盖。

2)如果用户一定要改变,则必须首先将布局管理器取消

setLayout(null)o随后通过组件方法改变。但这样做的结

果是程序的系统相关。

java.awt中提供的常用容器中:

1)Frame(框架)类是Window类的子类,它是窗口的一种,

有自己的标题,其缺省布局管理器为BordeLayout,在

一个程序中我们可以使用多个Frameo注意:一个Frame

刚被创建后,其初始大小为(0,0)而且是不可见的,所

以必须重设其大小,并且用setVisible(true)设置其为可

见。

2)Panel(画板)无法独立显示,必须添加到某个容器中。

Panel缺省的布局管理器为FlowLayouto

例:

importjava.awt.*;

publicclassExgui{

privateFramef;

privatePanelp;

privateButtonbw,bc,be;

privateButtonbfile,bhelp;

publicstaticvoidmain(Stringargs[]){

Exguigui=newExgui();

gui.go();

)

publicvoidgo(){

f=newFrame("GUIexameple");

bw=newButton("WEST");

bc=newButton("Workspaceregion");

be=newButton("Exit");

f.add(bw,"West");

f.add(bc,"Center");

p=newPanel();

f.add(p,"North");

bfile=newButton("File");

bhelp=newButton("help");

p.add(bfile);

p.add(bhelp);

f.pack。;//将Frame设置为紧凑格式

f.setVisible(true);

}

3、AWT的事件处理

AWT编程的思想就是通过各种各样的组件实现GUI,并且能

够实现和用户的交互。整个实现的过程充分体现的是面向对

象的思想。然而,整个用户交互的过程就是用户触发事件,

事件就是发生在用户界面上的用户交互行为所产生的一种效

果。

JDK1.1中的AWT处理事件由原来JDK1.0的事件传递改为事

件授权模型,即事件处理从一个事件源授权到一个或多个事

件监听器,组件作为事件源可以触发事件,通过

addXXXListener方法向组件注册监听器,一个组件可以注册

多个监听器,如果组件触发了相应的事件,此事件就被传送

以注册的监听器,事件监听器负责处理事件过程。

ActionEvent

actionPerformed(ActionEvent)

Frame监听器对象

使用授权处理模型进行事件处理的实现原理:(见课本P294)

在AWT中的事件共10类(课本P295),其中ActionEvent>

ItemEventAdjustementEventTextEvent为高级事件,其余为

低级事件。高级事件封装了GUI组件的语义模式,他们没有

同任何屏幕基础的组件相连,而是与具有一定语义的事件相

连。如ActionEvent能在按钮按下时被激活,也能在用户在

TextField组件敲回车时被激活。所以高级事件又叫语义事件。

4、Swing和AWT的区别:

Swing是AWT的发展,它具备了许多AWT所不具备的功

能,如可以显示图标等。在具体的使用过程中一般没有什

么特别强调,通常都用Swingo

5、AWT和Swing的区别

例:

importjavax.swing.*;

publicclassswing1{

publicstaticvoidmain(Stringargs[]){

JFrameframe=newJFrame("helloworld");

finalJLabellable=newJLabel("helloworld");

frame.getContentPane().add(lable);

frame.setSize(200,200);

frame.setVisible(true);

)

}

第十一章线程

1、线程的产生:

在Java语言产生前,传统的程序设计语言的程序同一时刻只能

单任务操作,效率非常低,例如程序往往在接收数据输入时发

生阻塞,只有等到程序获得数据后才能继续运行。随着Internet

的迅猛发展,这种状况越来越不能让人们忍受:如果网络接收

数据阻塞,后台程序就处于等待状态而不继续任何操作,而这

种阻塞是经常会碰到的,此时CPU资源被白白的闲置起来。如

果在后台程序中能够同时处理多个任务,该多好啊!应Internet

技术而生的Java语言解决了这个问题,多线程程序是Java语

言的一个很重要的特点。在一个Java程序中,我们可以同时并

行运行多个相对独立的线程,例如,我们如果创建一个线程来

进行数据输入输出,而创建另一个线程在后台进行其它的数据

处理,如果输入输出线程在接收数据时阻塞,而处理数据的线

程仍然在运行。多线程程序设计大大提高了程序执行效率和处

理能力。

计算机操作系统多任务的处理方式给程序设计提出了新的发展

方向,就是程序如何同样实现并行的处理?Java语言就是根据

操作系统的多任务性设计出可支持多个程序片段并行运行的机

制,即Java的多线程技术(此技术也是Java的重要特性之一)。

操作系统中的多任务是通过进程来控制,每个任务对应一个进

程,而Java中是通过线程来控制多任务的执行。

线程与进程的区别:

a)进程:每个进程都有独立的代码和数据空间,进程切换的开销

大;

b)线程:轻量的进程,同一类线程共享代码和数据空间,每个线

程有独立的运行栈和程序计数器,线程切换的开销小;

c)多进程:在操作系统中,能够同时运行多个任务(程序);

d)多线程:在同一个应用程序中,有多个顺序同时执行;

e)一个进程中可以包括多个线程;

2、线程的概念:

线程是一个程序内部的顺序控制流。

在前面所举的简单例子中,我们是对字符串进行处理,它的特

点是每个程序都有一个入口、一个出口以及一个顺序执行的序

歹U,在程序执行过程中的任何指定时间内,都只有一个单独的

执行点。线程也是只有一个入口、一个出口和一个顺序执行的

序列,但线程并不是程序,不能够单独运行,必须在程序中运

行。从概念上讲一个线程就是一个程序内部的顺序控制流。一

个线程是没有意义的,真正发挥作用的是在一个程序中实现多

个线程。

在多任务的Windows系统中,计算机可以同时执行多个程序,

而多线程则是在一个程序内部又可以同时进行多种运算。从逻

辑上讲,多线程意味着一个程序的多行语句同时执行,但是多

线程不等于多次启动一个程序,操作系统也不会把每个线程当

作进程对待。(具体事例描述见课本P245)

线程的概念模型:

1)虚拟的CPU,封装在java.lang.Thread类中;

2)CPU所执行的代码,传递给Thread类;

3)CPU所处理的数据,传递给Thread类;

理解:由于在实现线程时引用的包中必须有Run()方法,此方法

就代表启动CPU来处理这部分顺序代码,故此称为虚拟CPU;

而在定义线程时,线程要执行的代码和运算的数据就必须都传

给Thread类。

3、线程的使用:

a)线程体:Java的线程是通过Java的软件包java.lang中的类

Thread来实现的。当我们生成一个Thread类的对象之后,一

个新的线程就诞生了。这个线程实例表示Java解释器中真正

的线程,并作为控制和同步执行的一个句柄,通过它可以启动

一个线程、终止线程、或者暂停挂起它等。每个线程都是通过

某个特定对象的方法run()来完成其操作的,方法run()称为线

程体。在一个线程被建立并初始化以后,Java的运行时系统就

就可以启动线程start。,自动调用run()方法执行线程体。run()

方法就是线程执行的起点,象应用程序从main()开始、小应

用程序从init()开始一样。通常run()方法为一个循环。

b)线程体的构造:

正如课本P256中所提,构造线程通过在Java的软件包

java.lang中的类Thread来提供的构造方法:

publicThread(ThreadGroupgroup,Runnabletarget,String

name),其中,group指明该线程所属的线程组;target为实际执

行线程体的目标对象,它必须实现接口;name为线程名。在

此体现面向对象的思想,通过Tread()方法的多态性来根据实

际情况构造不同情况的线程即同一个方法有不同的参数。需要

解释的是线程体目标对象:前面提到线程是程序中的一段代

码,不能够单独运行,必须在程序中才能运行。在此提到的线

程体目标对象就是包含该线程体的类。

一个类声明实现Runnable接口,就意味着该类可以作为线程

体的目标对象。Runnable接口只定义了一个方法run()作为线

程体的构造空间。

由于类Thread本身也是实现了接口Runnable,因此可以通过

两种方法实现线程体。

1)定义一个线程类,它继承类Thread并重写其中的方法

run(),这时在初始化这个类的实例时,目标target为null,

表示由这个实例来执行线程体。

2)提供一个实现接口Runnable的类作为一个线程的目标对

象,在初始化一个Thread子类的线程对象时,把目标对

象传递给这个线程实例,由该目标对象提供线程体

run()o

3)两种方法定义的线程实例见课本。

两种方法的比较:

1)使用Runnable接口

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

型。在例子中,Thread对象clockThread中封装

了CPU、类Clock提供了线程执行的代码,当前

的Clock类实例this提供了线程运行时需要的

数据。

2.还可以继承其他类。

3.保持程序风格的一致性。

2)直接继承Thread类

1.不能继承其他类。

2.编写简单,可以直接操作线程,无须使用

Thread.currentThread()。

3.事例:

//通过Thread类的子类创建的线程;

classthread1extendsThread

{file:〃自定义线程的run。方法;

publicvoidrun()

(

System.out.println("Thread1isrunning---");

)

)

file:〃通过Runnable接口创建的另外一个线程;

classthread2implementsRunnable

{file:〃自定义线程的run()方法;

publicvoidrun()

(

System.out.println("Thread2isrunning---");

)

)

file://程序的主类’

classMulti_Threadfile://声明主类;

(

plubicstaticvoidmail(Stringargs[])file:〃声明主方法;

threadlthreadone=newthreadl();file://fflThread

类的子类创建线程;

Threadthreadtwo=newThread(newthread2());file:〃用

Runnable接口类的对象创建线程;

threadone.start();threadtwo.start();file:〃strat()方法启

动线程;

)

)

运行该程序就可以看出,线程threadone和threadtwo交替占用CPU,

处于并行运行状态。可以看出,启动线程的run()方法是通过调用线

程的start。方法来实现的(见上例中主类),调用start。方法启动线程

的run()方法不同于一般的调用方法,调用一般方法时,必须等到一

般方法执行完毕才能够返回start。方法,而启动线程的run()方法后,

start。告诉系统该线程准备就绪可以启动run()方法后,就返回start()

方法执行调用start。方法语句下面的语句,这时run()方法可能还在

运行,这样,线程的启动和运行并行进行,实现了多任务操作。

c)线程的状态:

线程作为一段可执行的程序段落,它的存在必然有个生命周

期。在一个线程的生命周期中它总是处于不同的状态。线程的

状态表示了线程正在进行的活动以及在这段时间内线程能完

成的任务。

线程状态图

1.创建状态(newThread)

声明方法:ThreamyTread=newMyThreadClass();

状态说明:由于没有启动这个线程,所以线程处于创建状

态时:它仅仅是个空的线程对象,系统不为其

分配资源。

可行操作:启动身体start。或终止stop()o

2.可运行状态(Runnable)

声明方法:ThreadmyThread=newMyThreadClass();

myThread.start();

状态说明:start。方法产生了运行这个线程所需的系统资

源,安排其运行,并调用线程体——run()方法。

可运行状态并不是运行中状态(单处理器所

致),但可以随时运行,不需要程序再去控制,

系统自动调度。

可行操作:yield。暂时挂起该线程,使其它优先级较高的

线程先运行。

stop。或run()exits停止线程。

3.不可运行状态Runnable:

当下面四种情况发生时,线程处于不可运行状态:

a)调用sleep。方法

b)调用suspend。方法

c)为等待一个变量,线程调用wait()方法

d)输入输出流中发生线程阻塞

如课本中的实例代码中的:myThread.sleep(10000),就是使

该线程休止10秒,这时即使处理器空闲,也不能执行该线

程,10秒后线程又成为可运行的。

对上面四种情况,都有特定的返回可运行状态的方法与之

对应。对应方法如下:

1.如果线程处于睡眠状态中,sleep。方法中的参数为休息

时间,当这个时间过去后,线程即可运行。

2.如果一个线程被挂起,须由其他线程调用resume。方法

来恢复该线程的执行。

3.如果线程在等待条件变量,那么要停止等待的话,需要

该条件变量所在的对象调用notify。或notifyAU()方法。

  • 上一篇: JAVA基础核心总结
  • 下一篇: java基础细节
  • 版权声明


    相关文章:

  • JAVA基础核心总结2025-04-22 11:26:05
  • java语言程序设计基础篇 进阶篇2025-04-22 11:26:05
  • java基础变量2025-04-22 11:26:05
  • java基础程序认识2025-04-22 11:26:05
  • java基础命名2025-04-22 11:26:05
  • java基础细节2025-04-22 11:26:05
  • 学完java基础学什么2025-04-22 11:26:05
  • java三大基础是什么2025-04-22 11:26:05
  • 高斯java基础2025-04-22 11:26:05
  • java语法基础412025-04-22 11:26:05