第 8 章

38
第 8 第 异异异 异异异

Upload: brian-cabrera

Post on 30-Dec-2015

39 views

Category:

Documents


5 download

DESCRIPTION

第 8 章. 异 常处理. 一、程序中的错误. 《 编译错误 》 由于所编写的程序存在语法问题,未能通过由源代码到目标代码的编译过程而产生的错误。它将由语言的编译系统负责检测和报告。 《 运行错误 》 在程序的运行过程中产生的错误。. 二、 Java 对异常的处理机制. Java 使用异常对 Java 程序给出一个统一和相对简单的 抛出 和 处理 错误的机制。如果一个方法本身能抛出异常,当所调用的方法出现异常时,调用者可以 捕获 异常使之得到处理;也可以 回避 异常,这时异常将在调用的堆栈中向下传递,直到被处理。. b. a. c. d. 必须解决. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第  8  章

第 8 章

异 常处理异 常处理

Page 2: 第  8  章

一、程序中的错误 《编译错误》 由于所编写的程序存在语法问题,未能

通过由源代码到目标代码的编译过程而产生的错误。它将由语言的编译系统负责检测和报告。

《运行错误》 在程序的运行过程中产生的错误。

Page 3: 第  8  章

二、 Java 对异常的处理机制 Java 使用异常对 Java 程序给出一个统一

和相对简单的抛出和处理错误的机制。如果一个方法本身能抛出异常,当所调用的方法出现异常时,调用者可以捕获异常使之得到处理;也可以回避异常,这时异常将在调用的堆栈中向下传递,直到被处理。

Page 4: 第  8  章

发现异常自行处理

必须解决 自行解决或将其抛出。

发现异常不自行解决,将其抛出。

a b c d

Page 5: 第  8  章

异常类

Error 类对象由 Java 虚拟机生成并抛出;Exception 类对象由应用程序处理或抛出。Throwable 类是类库 java.lang 包中的一个类

Object

Throwable

Error Exception

AWTException IOException RuntimeException

Page 6: 第  8  章

Exception 类的主要方法public Exception( );

public Exception(String s); 可以接受字符串参数传入的信息,

该信息通常是对该例外所对应的错误的描述。• public String toString( ); 返回描述当前 Exception 类信息的

字符串。• public void printStackTrace(); printStackTrace() 方法没有返回值,它的功能是完成一个

打印操作,在当前的标准输出(一般就是屏幕)上打印输出当前例外对象的堆栈使用轨迹,也即程序先后调用执行了哪些对象或类的哪些方法,使得运行过程中产生了这个例外对象。

Page 7: 第  8  章

三、异常处理

对运行时异常可以不做处理,由 Java 虚拟机自动进行处理;

使用 Try-catch-finally 语句捕获处理;通过 throws 子句声明抛弃异常,还可以

定义自己的异常类,并用 throw 语句抛弃。

Page 8: 第  8  章

1 、运行时异常 运行时异常是由 Java 运行时系统在

程序的运行过程中检测到的。它可能在程序的任何部位发生,而且其数量可能很大,因此 Java 编译器允许程序不对它进行处理。这时, Java 系统会把生成的运行时异常对象交给缺省的异常处理程序,在标准输出设备上显示异常的内容以及发生异常的位置。

Page 9: 第  8  章
Page 10: 第  8  章

class ArrayOutOf

{ public static void main(String[ ] args)

{

char[ ] buf = {'a', 'b', 'c'};

int i;

for (i = 0; i < buf.length; i++)

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

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

}

}

Page 11: 第  8  章
Page 12: 第  8  章

public class StringIndexOutOf {

public static void main(String args[ ])

{

String str = "abc";

System.out.println(str.charAt(3));

}

}

Page 13: 第  8  章
Page 14: 第  8  章

2 、捕获异常并进行处理try{ 调用产生异常的方法及其他 java 语句; }catch (异常类名 异常对象名){ 异常处理; }catch (异常类名 异常对名){ 异常处理; }......finally{ 最终处理; }

Page 15: 第  8  章

public class TryCatchFinally

{ public static void main( String args[ ] )

{ Method( 0 ); Method( 1 ); Method( 2 ); }

static void Method( int a )

{ System.out.println(" 调用方法 Method("+a+")");

try

{ if( a==0 )

{ System.out.println("\t 没 有 异 常 产 生 , 正 常 退出。 ");

return; }

else if( a==1 )

{ int i=0; int j=4/i; }

else if ( a==2 )

{ int iArray[ ]=new int[4]; iArray[4]=3; }

}

Page 16: 第  8  章

catch( ArithmeticException e )

{ System.out.println("\t 捕获异常: "+e); }

catch( ArrayIndexOutOfBoundsException e )

{ System.out.println("\t 捕获异常: "+e.getMessage( )); }

catch( Exception e )

{ System.out.println(“\t 产生的异常已被处理, 该 catch 块不会被执行。 "); }

finally

{ System.out.println("\tfinally 块总是被执行。 "); }

}

}

Page 17: 第  8  章
Page 18: 第  8  章

3 、抛出异常 在有些情况下,一个方法并不需要处理它

所生成的异常,而是向上传递,由调用它的方法来处理这些异常,这时就要用到 th

row 子句。其格式如下:返回类型 方法名( [ 参数表 ] ) throw 异常名列

Page 19: 第  8  章

public class throws Exception

{ public static void main( String args[] )

{ try

{ Method( 0 ); Method( 1 ); }

catch(NumberFormatException e )

{System.out.println("\t 捕获异常: "+e);}

catch( ArrayIndexOutOfBoundsException e )

{System.out.println("\t 捕获异常: "+e);}

finally

{System.out.println(“finally 块总是会被执行 .”); }

}

Page 20: 第  8  章

static void Method( int i )

throws ArithmeticException,NumberFormatException

{ System.out.println(" 调用方法 Method("+i+")");

if( i==0 )

{ System.out.println(“\t 没有异常事件。” ); return; }

else if( i==1 )

{ String str = "xyz";

int c;

c=Integer.parseInt(str);

}

}

}

Page 21: 第  8  章
Page 22: 第  8  章

4 、抛出异常 在捕获异常之前,必须有一段 Java

代码生成一个异常对象并将它抛出。异常对象的生成和抛出可以有三种情况: Java 运行时系统; JDK 中某个类; 在程序中创建异常对象并抛出。

Page 23: 第  8  章

public class TestThrowException

{ static double sqrt(double i) throws IllegalArgumentException

{ if (i < 0) {

IllegalArgumentException e=new IllegalArgumentException

("Cannot take square root of a negative number");

throw e;}

return (Math.sqrt(i));

}

public static void main(String[] args)

{ System.out.println("IllegalArgumentException example");

try { System.out.println(sqrt(-4)); }

catch (IllegalArgumentException e)

{ System.out.println(e.getMessage()); }

}

}

Page 24: 第  8  章
Page 25: 第  8  章

public class TestMyException

{ static void Method( int a ) throws MyException

{ System.out.println(" 调用方法 Method("+a+")");

if( a>10|a<0 ) throw new MyException(a);

System.out.println("\t 正常退出。 ");

}

public static void main( String args[ ] )

{ try

{ Method( 1 ); Method( -6 );}

catch( MyException e )

{ System.out.println("\t 捕获异常: "+e.toString()); }

}

}

Page 26: 第  8  章

class MyException extends Exception

{

private int detail;

MyException( int a )

{

detail = a;

}

public String toString( )

{

return "MyException "+detail;

}

}

Page 27: 第  8  章
Page 28: 第  8  章

四、创建用户自己的异常

class 自定义异常 extends 父异常类名 { 类体 ; }

《举例》class NumberRangeException extends Exception

{

NumberRangeException(String msg)

{ super(msg); }

}

Page 29: 第  8  章

class MyException extends Exception{ // 自定义的异常类子类 MyExceptionpublic MyException(){// 用户异常的构造函数}public MyException(String s){ super(s); // 调用父类的 Exception 的构造函数

}public String toString(){ // 重载父类的方法,给出详细的错误信息

…}

…}

Page 30: 第  8  章

《抛出异常的格式》 [ 修饰符 ] 返回类型 方法名(参数 1 , 参数 2 ,……) throws 自定义异常{

…………..

if (条件满足)throw (new myException(this));

else

…………….

}

Page 31: 第  8  章

• 创建用户自定义异常时,一般需要完成如下的工作:

• ( 1 )声明一个新的异常类,使之以 Exception 类或其他某个已经存在的系统异常类或用户异常为父类

• ( 2 )为新的异常类定义属性和方法,或重载父类的属性和方法,使这些属性和方法能够体现该类所对应的错误的信息。

Page 32: 第  8  章

class IllegalSalaryException extends Exception{ // 用户定义的工资不合法异常private Employee m_ConcernedEmp; // 产生异常时的 Employee 类的引用private double m_IllegalSalary;IllegalSalaryException(Employee emp,double isal){ // 构造函数super(" 工资低于最低工资 ");m_ConcernedEmp=emp;m_IllegalSalary=isal;} public String toString(){ // 给出具体的错误信息 String s;s=" 为雇员提供的工资不合法:雇员: "+m_ConcernedEmp.

getEmpName() +" 非法工资: "+m_IllegalSalary+" 低于最低工资数额 800元 ";

return s;}}

Page 33: 第  8  章

• class IllegalSalaryChangeException extends Exception• {// 用户定义的工资变动不合法异常• private Employee m_ConcernedEmp; • // 产生异常时的 Employee 类的引用• private double m_IllegalSalaryChange; IllegalSalaryChangeException(Employee emp,double csal) { // 构造函数• super(" 工资变动太大 ");• m_ConcernedEmp=emp;• m_IllegalSalaryChange=csal; } public String toString(){ // 给出具体的错误信息• String s;• s=" 为雇员提供的工资变动不合法 : 雇员: "+m_ConcernedEmp.ge

tEmpName()+" 非法变动工资变化: "+m_IllegalSalaryChange+"高于原工资的 20% ";

• return s;• }}

Page 34: 第  8  章

• import java.applet.Applet;• import java.awt.*;

• public class UserException extends Applet{• Employee Emp;• Label prompt1=new Label("请输入雇员姓名和工资初值: ");• Label prompt2=new Label("请输入欲修改的工资: ");• TextField name,isal,nsal;• String msg;

• public void init(){• name=new TextField(5);• isal=new TextField(5);• nsal=new TextField(5);• add(prompt1);add(name);add(isal);• add(prompt2);add(nsal);• }• public void paint(Graphics g){• g.drawString(msg,0,80);• }

Page 35: 第  8  章

• public void CreateEmp(String en,double sa){• try{• Emp=new Employee(en,sa);• msg=new String(Emp.toString());• }• catch(IllegalSalaryException ise){• msg=new String(ise.toString());• }• }• public void ChangSal(double cs){• try{• Emp.setEmpSalary(cs);• msg=new String(Emp.toString());• }• catch(IllegalSalaryException ise){• msg=new String(ise.toString());• }• catch(IllegalSalaryChangeException isce){• msg=new String(Emp.toString()+isce.toString());• }• }

Page 36: 第  8  章

• public boolean action(Event e,Object o){• String en;• double es,cs;

• if(e.target==isal){• en=new String(name.getText());• es=Double.valueOf(isal.getText()).doubleValue();• CreateEmp(en,es);• }• else if(e.target==nsal){• if(Emp!=null){• cs=Double.valueOf(nsal.getText()).doub

leValue();• ChangSal(cs);• }• else• msg=new String("请先输入雇员姓名工

资并创建之 ");• }• repaint();• return true;• }• }

Page 37: 第  8  章

• class Employee{• String m_EmpName;• double m_EmpSalary;

• Employee(String name,double initsal) throws IllegalSalaryException{

• m_EmpName=new String(name);• if(initsal<800)• throw(new IllegalSalaryException(this,in

itsal));• m_EmpSalary=initsal;• }• public String getEmpName(){• return m_EmpName;• }• public double getEmpSalary(){• return m_EmpSalary;• }

Page 38: 第  8  章

• public boolean setEmpSalary(double newsal)• throws IllegalSalaryException,IllegalSalaryChangeExce

ption• {• if(newsal<800)• throw(new IllegalSalaryException(this,newsa

l));• else if(Math.abs(newsal-getEmpSalary())/getEmpSalary

()>=0.2)• throw(new IllegalSalaryChangeException(this,

newsal-getEmpSalary()));• else{• m_EmpSalary=newsal;• return true;• }• }• public String toString(){• String s;• s="姓名: "+m_EmpName+" 工资: "+m_EmpSalary;• return s;• }• }