Java程序设计基础实验指导书

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

JA V A程序设计实验指导书
撰写者:陈洺均
单位:信息工程系
2011-08-15
实验一在DOS环境下编译和运行Application和Applet程序
实验目的:
(1)熟悉JDK7.0工作环境。

(2)掌握开发JA V A应用程序和Applet程序的步骤:编写源文件、编译源文件和运行文件。

(3)掌握JDK7.0提供的开发工具javac、java、appletviewer的使用方法。

实验要求:
(1)编写一个简单的Java应用程序,该程序在命令行窗口输出两行文字:“你好,很高兴学习Java”和自己的学号和姓名。

(2)使用文本编辑器编写一个Java applet程序,在Applet显示窗口中显示“HelloWorld”,并通过以下两种方式来运行改程序:在DOS环境下编译后直接在浏览器中运行该程序和是使用appletviewer来运行该程序。

实验步骤:
1、在DOS环境下编译运行Application
(1)下载安装Jdk7.0,配置环境变量
JDK7.0是最新的Java EE的安装包,首先通过官方网站下载该安装包进行应用程序的安装,下面是安装jdk的步骤:
①双击下载的jdk-7-windo ws-i586.exe。

②选择安装路径,默认的安装路径是(C:\P rogr a mfile s\J a va\jdk1.7.0),可以根据你实际的安装路径修改;在安装J DK1.6时,会同时安装好J RE1.7,默认的安装路径为(C:\P rogr a m f iles\J a va\jr e7)。

⑵安装完jd k后,我们要设置J a va环境变量,设置J a va环境变量的步骤
如下:
①点击“我的电脑”右键――属性――高级――环境变量;在环境变量对话框的系统变量栏中点击新建,在弹出的新建系统变量中设置:
变量名:J AVA_HOME
变量值:C:\P rogra mFiles\J a va\jdk1.7.0(根据你的实际安装路径填写)
②在系统变量中找到path变量――点击编辑,在变量值的最前面添加值C:\Progr am Fil es\J ava\jdk1.7.0\b in; (根据你的实际安装路径填写)
③在系统变量中新建classpath,变量值.;C:\Program Files\Java\jdk1.6.0_07\lib\dt.jar;
C:\Program Files\Java\jdk1.6.0_07\lib\tools.jar; (根据你的实际安装路径填写)
最后:点击确定,环境变量设置成功。

⑵应用程序安装好后,可以通过下面方式编译、执行Java应用程序。

设置好JDK7.0的路径后,使用任意文本编辑器如文本文档编写源程序,编写好后,将文件保存成以HelloWorld.java为文件名的文件。

打开命令提示符,使用DOS命令进入HelloWorld.java文件所存放的目录(如D:\Example),使用javac命令编译该程序,编译后会在该文件夹中生成一个名为HelloWorld.class的class文件,
命令格式如下所示:
D:\Example>javac HelloWorld.java //编译源文件
再使用java命令执行该class文件,可在控制台下看到执行结果。

命令格式如下所示:
D:\Example>java HelloWorld
注意:初学者在编译时可能会遇到下列错误提示。

●Command not Found 出现该错误的原因是没有设置好系统变量Path;
●File not Found 出现该错误的原因是没有将源文件保存在当前目录中。

例如
D:\Example,或源文件的名字不符合有关规定。

例如,错误地将源文件命名为
hello.java或Hello.java.txt。

要特别注意,java语言的标识符号是区分大小写的。

●出现一些语法错误提示,例如,在汉语输入状态下输入了程序中需要的语句分号等。

Java源程序中涉及到的小括号及标点符号都是英文状态下输入的。

D:\Example>java HelloWorld //运行程序
注意:初学者在编译时可能会遇到下列错误提示。

●Exception in thread “main”ng.NoClassFoundError 出现该错误的原因是没有
设置好系统变量ClassPath,或运行的不是主类的名字,或程序没有主类。

2、在DOS环境下编译运行Applet
设置好环境变量以后,用文本编辑器编辑文件名为SimpleApplet.java的java程序代码和SimpleApplet.html的HTML程序代码,并将它们存放在相同目录下(如:D:\Example)。

进入DOS环境,使用DOS命令进入目录D:\Example,使用javac编译SimpleApplet.java,编译后再使用浏览器或者使用appletviewer查看Applet运行结果。

在DOS环境下输入的命令格式为
D:\Example>javac SimpleApplet.java
D:\Example>appletviewer SimpleApplet.html
注意:
1. 在编写源文件时,源文件的后缀名要是.java,如果系统隐藏了文件的后缀名,以至你的文件名变为HelloWorld.java.txt时,编译会报错,报错原因是找不到源文件。

此时应该点击工具-文件夹选项-查看取消“隐藏已知文件的扩展名”前面的钩。

最后再重新改源文件的扩展名。

2. 如果你确定扩展名没有错误,但仍然找不到文件,那么请查看你当前所在的路径是否正确,或者在Dos提示符下输入的文件名大小写是否正确(Java是严格区分大小写的)。

如果以上几个方面均无误,那么就需要检查jdk是否安装正确。

实验后练习:
(1)在Application应用程序中,文件名和主类类名不相同,程序会报错吗?为什么?(2)在使用java命令运行时,java后面所跟的是public类还是主类,这两个类一定是同一个类吗?
(3)在Applet程序中的主类如果不用public修饰,编译能通过吗?程序能正确运行吗?
实验二输出希腊字母表
实验目的:
(1)掌握char类型数据和int型数据之间的相互转换,同时了解unicode字符表;
(2)掌握数据类型精度级别的高低;
(3)掌握数据类型之间转换规则。

实验要求:
(1)编写一个Java应用程序,该程序在命令行窗口输出希腊字母表。

实验步骤:
(1)为了输出希腊字母表,首先获取希腊字母表的第一个字母和最后一个字母在unicode 表中的位置,然后使用循环输出其余的希腊字母。

(2)要观察一个字符在unicode表中的顺序位置,必须使用int类型显示转换,如(int)’a’。

(3)使用循环,将希腊字母α到ω之间的所有字母顺序输出。

必须使用char类型显示转换,将其在unicode表中所表示的字符输出。

程序模板:
请按照要求,将【代码】替换成Java程序代码。

GreekAlphabet.java
public class GreekAlphabet
{
public static void main(String args[])
{
int startPos = 0, endPos = 0;
char cStart = 'α', cEnd = 'ω';
// cStart做int型数据转换,并将结果赋值给startPos
【代码1】
// cEnd做int型数据转换,并将结果赋值给endPos
【代码2】
System.out.println("字母α在unicode表中的顺序位置:" + startPos);
System.out.println("字母ω在unicode表中的顺序位置:" + endPos);
System.out.println("字母表:");
【代码3】//通过循环输出希腊字母表,并控制每行输出10个字符,
//字符与字符之间用空格隔开
}
}
程序运行的效果如下图:
实验后的练习:
(1)将一个double型数据直接赋值给float型变量,程序编译时提示怎样的错误?
(2)在应用程序的main方法中增加语句:float x=0.618; 程序能编译通过吗?
(3)在应用程序的main方法中增加语句:byte y=128; 程序能编译通过吗?
(4)在应用程序的main方法中增加语句:int z=(byte)128; 程序输出变量z的值是多少?
实验三鸽巢原理的模拟
实验目的:
(1)了解数组的定义、初始化等基本概念。

(2)了解和初步应用ng.Math类的random()方法处理实际问题。

(3)深入了解for循环,使用for循环顺序访问数组元素。

实验要求:
鸽巢原理的简单形式是:如果n+1个物体放进n个盒子,那么至少有一个盒子包含两个或更多物体。

假设有7个鸽子可以飞到6个鸽巢中,那么至少有一个鸽巢中会飞入两只或更多只鸽子。

编写程序模拟该问题。

实验指导:
●创建名为PigeonNest.java的文件,在该文件中利用Math.random( )随机方法(该方法的
取值是从0-1之间的小数)来模拟各自飞入鸽子的情况,来验证鸽巢原理。

●将程序PigeonNest.java中的代码填写完整,进行运行验证,如果某鸽巢的格子数目大于
2,则可验证成功。

程序模板如下:
import javax.swing.*;
public class PigeonNest{
int nest[];
public PigeonNest(){
nest=【代码1】/初始化鸽巢
for(int i=0;i<nest.length;i++)
{nest[i]=【代码2】//模拟第i+1只鸽子飞入到鸽巢nest[i]中;
}
String result="";
【代码3】//使用循环语句依次访问鸽子飞入鸽巢的编号
result+=【代码4】
JOptionPane.showMessageDialog(null,result,"运行结果
",RMA TION_MESSAGE);
}
public static void main(String [] args)
{PigeonNest pnest=new PigeonNest(); System.exit(0);
}
}
运行结果如下图:
实验四三角形、梯形和圆形的类封装
实验目的:
使用类来封装对象的属性和功能
实验要求:
编写一个Java应用程序,该程序中有3个类:Triangle、Lader和Circle,分别用来刻画三角形、梯形和圆形。

具体要求如下:
(1)Triangle类具有类型为double的三个边,以及周长、面积属性,Triangle类具有返回周长、面积以及修改三个边的功能。

另外,Triangle类还具有一个boolean型的属性,该属性用来判断三个数是否能够成一个三角形。

(2)Lader类具有类型为double的上底、下底、高和面积属性,具有返回面积的功能。

(3)Circle类具有类型为double的半径、周长和面积属性,具有返回周长和面积的功能。

实验指导:
创建一个对象时,成员变量被分配内存空间,这些内存空间称作该对象的实体或变量,而对象中存放着引用,以确保这些变量由该对象操作使用。

空对象不能使用,即不能让一个空对象去调用方法产生行为。

假如程序中使用了空对象,程序在运行时会出现异常:NullPointerException。

由于对象是动态分配实体,所以Java 的编译器对空对象不做检查。

因此在编写程序时要避免使用空对象。

程序模板如下:
class Triangle
{
double sideA, sideB, sideC, area, length;
boolean boo;
//初始化Triangle类的各成员变量,并判断是否满足构成三角形的条件
public Triangle(double a, double b, double c)
{
【代码1】
if(【代码2】)
{
【代码3】
}
else
{
【代码4】
}
}
//方法体,判断如果是三角形,则计算出Length的值并返回,否则输出不是三角形,不能//计算周长直接返回0
double getLength()
{
【代码5】
}
public double getArea()
{
if(boo)
{
double p = (sideA+sideB+sideC)/2.0;
area = Math.sqrt(p*(p-sideA)*(p-sideB)*(p-sideC));
return area;
}
else
{
System.out.println("不是三角形,不能计算面积");
return 0;
}
}
//给Triangle类的成员变量赋值,并判断是否满足构成三角形的条件
public void setABC(double a, double b, double c)
{
【代码6】
if(【代码7】)
{
【代码8】
}
else
{
【代码9】
}
}
}
class Lader
{
double above,bottom,height,area;
//完成初始化
Lader(double a,double b,double h)
{
【代码10】
}
//计算出area并返回
double getArea()
{
【代码11】
}
}
class Circle
{
double radius,area;
Circle(double r)
{
【代码12】
}
double getArea()
{
【代码13】
}
double getLength()
{
【代码14】
}
void setRadius(double newRadius) {
radius=newRadius;
}
double getRadius()
{
return radius;
}
}
public class AreaAndLength
{
public static void main(String args[])
{
double length, area;
Circle circle=null;
Triangle triangle;
Lader lader;
// 创建对象triangle,circle,lader
【代码15】
【代码16】
【代码17】
//调用各个方法返回需要的值
【代码18】
System.out.println("圆的周长:"+length);
【代码19】
System.out.println("圆的面积:"+area);
【代码20】
System.out.println("三角形的周长:" + length);
【代码21】
System.out.println("三角形的面积:" + area);
【代码22】
System.out.println("梯形的面积:" + area);
//调用Triangle方法设置三个边,要求将三个边修改为12,34,1
【代码23】
//调用Triangle方法返回面积赋值给area
【代码24】
System.out.println("三角形的面积:" + area);
//调用Triangle方法返回周长并赋值给length
【代码25】
System.out.println("三角形的周长:" + length);
}
}
实验后练习
(1)程序中仅仅省略【代码15】,编译能通过吗?
(2)程序中仅仅省略【代码15】,运行时出现怎样的异常提示?
(3)让AreaAndLength类中的circle对象调用方法修改半径,然后输出修改后的半径以及修改半径后的圆的面积和周长。

实验五方法的重载与This关键字
实验目的:
(1)理解变量的作用域;
(2)掌握成员变量、局部变量和块变量的区别;
(3)学会使用This关键字。

(4)理解方法重载的含义;
(5)学会使用方法重载。

实验要求:
(1)编写一个Java程序ScopeTest以反映变量的种类及其作用范围,类ScopeTest中既有类的成员变量,又有方法中的局部变量和参数,甚至还有在方法内部的块中声明的变量,仔细体会这些变量的差异及其用法。

(2)编写一个Java程序,反映出方法重载的使用特点,该程序包含多个重载的加法运算,如:整型加法、实型加法、以及混合加法运算等。

从中体会方法重载的用法和优点。

代码一:
class ScopeTest
{
int x;
static int m = 0;
void show()
{
int x = 8, y;
for(y=0; y<2; y++)
{
int z = 5;
System.out.println("z = " + z);
z = 10;
System.out.println("z = " + z);
System.out.println("方法域中的X =" + x + "在块内显示");
}
//z = 20;
System.out.println("方法域中的X =" + x + "在块外显示");
System.out.println("类域中的X =" + this.x + "在块外显示");
System.out.println("类域中的m =" + this.m + "在块外显示");
}
void setx(int x)
{
this.x = x;
}
static void setm(int m)
{
ScopeTest.m = m;
}
public static void main(String[] args)
{
ScopeTest application = new ScopeTest();
application.setx(2);
application.setm(3);
application.show();
}
}
代码二:
//Overload.java
class Overload{
int m,n;
Overload(){
m=0;
n=0;
}
Overload(int a,int b){
【代码1】//初始化变量m,n
}
int add(){
System.out.println("无参加法"+m+"+"+n+"="+(m+n));
return m+n;
}
int add(int a,int b){
System.out.println("整型加法"+a+"+"+b+"="+(a+b));
return a+b;
}
double add(double a,double b){
System.out.println("实型加法"+a+"+"+b+"="+(a+b));
return a+b;
}
double add(int a,int b,double c){
System.out.println("混合加法"+a+"+"+b+"+"+c+"="+(a+b));
【代码2】//返回加法运算的结果
}
public static void main(String[] args){
int ix,iy;
double dx,dy;
【代码3】//声明一个Overload对象ov并初始化
ix=ov.add();
iy=ov.add(3,6);
【代码4】//调用实型加法函数参数为2.1,5.3
dy=ov.add(3,6,2.2);
}
}
实验后练习:
代码一:
(1)仔细阅读并分析程序,在编译运行之前,请写下分析得出的运行结果。

程序分析结果:
然后在JDK下编译运行程序观察与分析结果是否一致。

(2)请将程序中的语句//z=20;前面的注释符去掉,编译会报错吗?为什么?
(3)程序中有两个方法setx()与setm(),它们分别是对类中的数据x和m进行设置,不过正如所看到的,在方法setm()中使用的是ScopeTest.m=m,先在请将它改为this.m=m,编译程序是否会报错,如果确实会报错,请再将setm()方法前面的static 修饰符去掉,看看能否编译成功,并解释其中的原因。

(4)在程序中的方法show()中定义了一个循环语句,在这个循环语句块里声明了一个变量z,现在请将这个变量z的名字改为y,编译程序,观察有什么情况发生。

代码二:
(1)现在向程序中添加一个如下的新add()方法。

double add(int a, int b){
System.out.println("整型加法但返回实型值"+a+"+"+b+"="+(a+b));
return (double)(a+b);
}
编译时会出现什么情况,这说明了什么问题?
(2)程序中的add()方法,能进行整型、实型等加法,现在请再添加一个add()方法,能进行整型、实型等加法,现在请再添加一个add()方法使之能够进行两个复数之间的加法。

实验六实例成员与类成员
实验目的:
(1)掌握实例变量与类变量。

(2)掌握实例方法与类方法的区别。

实验指导:
(1)成员变量分为实例变量和类变量,用Static修饰的变量叫做类变量,也称为静态变量,实例变量是属于某个对象的,在对象创建时被分配内存,每个对象都会有自己的实例变量的空间;类变量是属于类的,在加载类的时候被分配内存,所有的对象都共享一个内存。

修改某个对象的实例变量的值,不会影响别的对象的实例变量。

(2)实例变量只能通过对象名来进行调用,而类变量则既可以通过类名调用,又可以通过对象名调用。

(3)在实例方法中既可以调用实例变量,又可以调用类变量,但在类方法中,则只能调用类变量,而不能调用实例变量。

实验要求:
一、编写源程序,注意输出结果并能正确解释输出结果
●在类A中有float类型的实例变量a和float类型的类变量b;实例方法setA()实现将float
类型的参数a赋给成员变量a;方法setB将float类型的参数b赋给成员变量b;方法getA()和getB()分别返回a和b;方法outputA()和outputB()分别输出a和b的值;
●在main方法中要做的操作如下:
通过类名操作变量b,并赋值为100;
调用方法inputB();
创建两个A类的对象cat和dog;
通过cat调用方法setA,将cat的成员a设置为200;
cat调用setB,将cat的成员b设置为400;
dog调用方法setA,将dog的成员a设置为150;
dog调用发法setB,将dog的成员b设置为300;
cat和dog分别调用outputA,outputB输出结果。

实验后练习:
(1)如果outputA()方法中输出a+b,编译是否会报错,为什么?
(2)如果outputB()方法中输出a+b,编译是否会报错,为什么?
二、编写实现:有一个三角形类Triangle,成员变量有底边x和另一条边y,和两边的夹角a(0<a<180),a为静态成员,成员方法有两个:求面积s(无参数)和修改角度(参数为角度)。

构造函数为 Triangle(int x,int y,int a) 参数分别为x,y,a赋值。

在main方法中构造两个对象,求出其面积,然后使用修改角度的方法,修改两边的夹角,再求出面积值。

(提示:求高的方法 h=y*Math.sin(a) )
实验七类的继承性
实验目的:
巩固如下概念:
●子类的继承性
●子类对象的创建过程
●成员变量的继承与隐藏
●方法的继承与重写
实验要求:
编写一个Java应用程序,除了主类外,该程序中还有四个类:People、ChinaPeople、AmericanPeople和BeijingPeople类。

要求如下:
●People类有访问权限是protected的double型成员变量:height和weight,以及public
void speakHello()、public void averageHeight()和public void averageWeight()方法。

●ChinaPeople类是People的子类,新增了public void chinaGongfu()方法。

要求
ChinaPeople重写父类的public void speakHello()、public void averageHeight()和
public void averageWeight()方法。

●AmericanPeople类是People的子类,新增public void AmericanBoxing()方法。

要求
AmericanPeople重写父类的public voidspeakHello()、public void averageHeight()和
public void averageWeight()方法。

●BeijingPeople类是ChinaPeople的子类,新增public void beijingOpera()方法。

要求
ChinaPeople重写父类的public void speakHello()、public void averageHeight()和
public void averageWeight()方法。

程序模板如下:
class People{
protected double weight,height;
public void speakHello()
{System.out.println("yayawawa");
}
public void averageHeight()
{height=173;
System.out.println("average height:"+height);
}
public void averageWeight()
{weight=70;
System.out.println("average weight:"+weight);
}
}
class ChinaPeople extends People{
【代码1】//重写speakHello方法,输出“你好”
【代码2】//重写averageHeight方法,输出“中国人的平均身高:173.0厘米”
【代码3】//重写averageWeight方法,输出“中国人的平均体重:67.34公斤”public void chinaGongfu(){
【代码4】//输出“坐如钟,站如松,睡如弓”
}
}
class AmericanPeople extends People{
【代码5】//重写speakHello方法,输出“How do you do ”
【代码6】//重写averageHeight方法,输出“American's averageHeight:188.0cm”
【代码7】//重写averageWeight方法,输出“American's averageWeight:80.23kg”public void americanBoxing()
【代码8】//输出“AmericanBoxing”
}
}
class BeijingPeople extends ChinaPeople{
【代码9】//重写speakHello方法,输出“你吃饭了吗”
【代码10】//重写averageHeight方法,输出“北京人的平均身高:173.0厘米”【代码11】//重写averageWeight方法,输出“北京人的平均体重:68.5公斤”public void beijingOpera()
【代码12】//输出“京剧”
}
public class Example {
public static void main(String [] args){
ChinaPeople chinaPeople=new ChinaPeople();
AmericanPeople americanPeople=new AmericanPeople();
BeijingPeople beijingPeople=new BeijingPeople();
chinaPeople.speakHello();
americanPeople.speakHello();
beijingPeople.speakHello();
chinaPeople.averageHeight();
americanPeople.averageHeight();
beijingPeople.averageHeight();
chinaPeople.averagWeight();
americanPeople.averagWeight();
beijingPeople.averagWeight();
chinaPeople.chinaGongfu();
americanPeople.americanBoxing();
beijingPeople.beijingOpera();
beijingPeople.chinaGongfu();
【代码13】//分别创建chinaPeople、americanPeople、beijingPeople的上转型对象,并//用它来调用可以调用的方法,来验证跟继承有关的多态性。

}
}
实验后练习
(1)就本程序而言,People类中的
public void speakHello()
public void averageHeight()
public void averageWeight()
三个方法的方法体中的语句是否可以省略。

实验八接口回调
实验目的:
●掌握接口
●掌握接口回调技术
实验指导:
1. 引入接口的原因:在程序设计中经常遇到这样一个问题:有些类互不相关,但却具有相似的功能。

并且功能在各个类中的实现互不相同。

我们不能为这些类定义一个共同的父类,但又希望在程序中体现出它们共同的接口。

2. 接口是一系列常量和空方法的集合,它提供了多个类共同的方法,但不限制每个类如何实现这些方法。

Java允许一个类同时实现多个接口,相当于实现多继承的功能。

3. 接口回调是指:将一个接口的实现类对象的引用赋值给一个接口变量,通过该接口变量来调用接口中的方法,实际上是通知相应的实现类对象来调用实现类中实现的方法,可以体现面向对象的多态性。

实验要求:
卡车要装载一批货物,货物有3种商品:电视、计算机和洗衣机。

需要计算出大货车和小货车各自所装载的3种货物的总重量。

要求有一个ComputeWeight接口,该接口中有一个方法:
public double computeWeight()
有3个实现该接口的类:Television、Computer和WashMachine。

这3个类通过实现接口computeTotalSales给出自重。

有一个Car类,该类用ComputeWeight接口类型的数组作为成员,那么该数组的单元就可以存放Television对象的引用、Computer对象的引用或WashMachine对象的引用。

程序能输出Car对象所装载的货物的总重量。

实验指导
由于数组goods的每个单元存放的是实现ComputerWeight接口的对象的引用,实验中的【代码5】可以通过循环语句让数组goods的每个单元调用computerWeight()方法,并将该方法返回的值累加到totalWeights。

程序模板如下:
interface ComputerWeight
{
double computeWeight();
}
class Television implements ComputerWeight
{
【代码1】
}
class Computer implements ComputerWeight
{
【代码2】
}
class washMachine implements ComputerWeight
{
【代码3】
}
class Car
{ ComputerWeight[] goods;
double totalWeights=0;
Car(ComputerWeight[] goods)
{
【代码4】
}
public double getTotalWeights()
{
totalWeights=0;
【代码5】
}
}
public class Road
{
public static void main (String args[])
{
ComputerWeight[] goodsOne=new ComputerWeight[50],
goodsTwo=new ComputerWeight[22];
for (int i=0;i<goodsOne.length;i++)
{ if(i%3==0)
goodsOne[i]=new Television();
else if(i%3==1)
goodsOne[i]=new Computer();
else if(i%3==2)
goodsOne[i]=new washMachine();
}
for (int i=0;i<goodsTwo.length;i++)
{ if(i%3==0)
goodsTwo[i]=new Television();
else if(i%3==1)
goodsTwo[i]=new Computer();
else if(i%3==2)
goodsTwo[i]=new washMachine();
}
Car 大货车=【代码6】
System.out.println("大货车装载的货物重量"+【代码7】);
Car 小货车=【代码8】
System.out.println("小货车装载的货物重量"+【代码9】);
}
}
实验后练习
1、请在实验的基础上再编写一个实现ComputerWeight接口的类,比如Refrigerator。

这样一来,大货车或小货车装载的货物中就可以有Refrigerator类型的对象。

2、增加一个实现ComputerWeight接口的类后,Car类需要进行修改吗?
实验九异常处理
实验目的:
1. 了解Java异常处理(exception)的作用。

2. 掌握异常处理的设计方法。

3. 掌握自定义异常类。

实验要求:
1. 理解系统异常处理的机制和创建自定义异常的方法。

实验前的基本知识:
一了解异常处理机制
1.错误与异常
在程序执行期间,会有许多意外的事件发生。

例如,程序申请内存时没有申请到、对象还未创建就被使用、死循环等,称为运行错误。

根据错误的性质将运行错误分为错误与异常两种类型。

(1)错误
程序进入了死循环或内存溢出,这类现象称为错误或致命性错误。

错误只能在编程阶段解决,运行时程序本身无法解决,只能依靠其它程序干预,否则会一直处于一种不正常的状态。

(2)异常
运算时除数为0或操作数超出数据范围,打开一个文件时发现文件不存在,网络连接中断等等,这类运行错误现象称为异常。

对于异常情况,可在源程序中加入异常处理代码,当程序出现异常时,由异常处理代码调整程序运行流程,使程序仍可正常运行直到结束。

由于异常是可以检测和处理的,所以产生了相应的异常处理机制。

而错误处理一般由系统承担。

2.异常发生的原因
(1)Java 虚拟机检测到了非正常的执行状态,这些状态可能是由以下几种情况引起的:·表达式的计算违反了Java 语言的语义,例如整数被0 除。

·在载入或链接Java 程序时出错。

·超出了某些资源限制,例如使用了太多的内存。

(2)Java 程序代码中的throw 语句被执行。

(3)异步异常发生。

异步异常的原因可能有:
·Thread 的stop 方法被调用。

·Java 虚拟机内部错误发生。

3.异常处理机制
(1)抛出异常
Java 是这样规定的:当语义限制被违反时,将会抛出(throw)异常,即产生一个异常事件,生成一个异常对象,并把它提交给运行系统,再由运行系统寻找相应的代码来处理异常。

一个异常对象可以由Java 虚拟机来产生,也可以由运行的方法生成。

异常对象中包含了异常事件类型、程序运行状态等必要信息。

(2)捕获异常
异常抛出后,运行时系统从生成异常对象的代码开始,沿方法的调用栈进行查找,直到找到包含相应处理的方法代码,并把异常对象交给该方法为止,这个过程称为捕获(catch)异常。

简单说异常处理机制就是:当语义限制被违反时,将会抛出异常对象,并将引起程序
流程从异常发生点转移到程序员指定的处理异常方法代码处进行异常处理。

二.了解异常对象的类型
在异常发生后,系统会产生一个异常事件,生成一个异常对象,有哪些异常对象呢?常见的异常类如下所示:
(1)RuntimeException 运行时异常类,主要包括以下异常子类:·ArithmeticException 算术异常类:表示遇到了异常的算术问题,例如被0 整除。

·ArrayStoreException 试图把与数组类型不相符的值存人数组。

·ClassCastException 类型强制转换异常类:试图把一个对象的引用强制转换为不合适的类型。

·IndexOutOfBoundsException 下标越界异常类:下标越界。

·NullPointerException 空指针异常类:试图使用一个空的对象引用。

·SecurityException 违背安全原则异常类:检测到了违反安全的行为。

(2)NoSuchMethodException 方法未找到异常
(3)java.awt.AWTException 图形界面异常类
(4)java.io.IOException 输入输出异常类
·IOException:申请I/O 操作没有正常完成。

·EOFException:在输入操作正常结束前遇到了文件结束符。

·FileNotFoundException:在文件系统中,没有找到由文件名字符串指定的文件。

(5)Exception 异常类的其它子类
·EmptyStackException:试图访问一个空堆栈中的元素。

·NoSuchFieldException:试图访问一个不存在的域。

·NoSuchMethodException:试图访问不存在的方法。

·ClassNotFoundException:具有指定名字的类或接口没有被发现。

·CloneNotSupportedException:克隆一个没有实现Cloneable 接口的类。

·IllegalAccessException:试图用给出了完整的路径信息的字符串加载一个类,但是当前正在执行的方法无法访问指定类,因为该类不是public 类型或在另一个包中。

·InstantiationException:试图使用Class 的newInstance 方法创建一个对象实例,但指定的对象没有被实例化,因为它是一个接口、抽象类或者一个数组。

·InterruptedException:当前的线程正在等待,而另一个线程使用了Thread 的interrupt 方法中断了当前线程。

三.使用try…catch 语句处理异常
1. 异常类型匹配的程序
如果在catch 语句中声明的异常类是Exception,catch 语句也能正确地捕获,这是因为Exception 是所有异常类的父类。

如果不能确定会发生哪种情况的异常,那么最好指定catch的参数为Exception,即说明异常的类型为Exception。

2.异常类型不匹配的程序
如果程序抛出的异常和catch中声明的异常类型不匹配,那么,程序可以通过编译但在运行时,系统会给出异常报告:报告所发生的但没有被捕获的异常。

不过在此之前,其它语句和finally 语句将会被执行。

3.包含多个catch 子句的异常处理程序
如果程序可能抛出多个异常,则对可能抛出的异常都要进行捕获,在捕获的过程中注意catch语句的顺序,如果这些异常具有继承关系,在捕获时必须采用从小到大,从特殊到一般的顺序进行捕获,否则编译会报错。

四.使用throw 语句抛出异常。

相关文档
最新文档