30
1 教教教教教教教教教教教 教教教教教教教 教教教教教 教教教教 教教教教教教 教教教教教教教教教 教教教教教教教 教教教教教教教教 教教3 教 9 教教教教教

第 9 章 异常处理

Embed Size (px)

DESCRIPTION

第 9 章 异常处理. 教学内容: 异常处理的机制 捕获与处理异常 多异常处理 抛出异常 自定义异常类 重点: 异常处理的机制 捕获与处理异常 难点: 自定义异常类 学时: 3. 9.1 异常处理的基本概念. 9.1.1 错误与异常. 运行错误:系统运行错误和逻辑运行错误。 系统运行错误简称为错误,是指程序在执行过程中所产生对操作系统的损害。 逻辑运行错误是指程序不能实现程序员的设计意图和设计功能而产生的错误,这种错误也被称为异常。. 9.1.2 Java 异常处理机制. - PowerPoint PPT Presentation

Citation preview

1

教学内容: 异常处理的机制 捕获与处理异常 多异常处理 抛出异常 自定义异常类

重点: 异常处理的机制 捕获与处理异常

难点: 自定义异常类学时: 3

第 9 章异常处理

2

9.1.1 错误与异常

运行错误:系统运行错误和逻辑运行错误。系统运行错误简称为错误,是指程序在执行过

程中所产生对操作系统的损害。 逻辑运行错误是指程序不能实现程序员的设计

意图和设计功能而产生的错误,这种错误也被称为异常。

9.1 异常处理的基本概念

3

9.1.2 Java 异常处理机制Java 异常处理机制 , 简单地说 , 就是程序在运行时 , 发

现异常的代码可以“抛出”一个异常,运行系统“捕获”该异常,并交由程序员编写的相应代码进行异常处理。

Public class ExceptionDemo{ public static void main(String args[]){ int a=0; System.out.println(8/a); } }

jvm: 产生异常对象 抛出异常对象java 程序: 捕获异常 (catch) 处理异常

4

9.2 异常处理类

Java 语言中定义了很多异常类,而每个异常类都代表一种运行错误

Java 的异常类是处理运行时错误的特殊类,类中包含了该运行错误的信息和处理错误的方法等内容。

程序对错误与异常的处理方式有三种:1. 程序不能处理的错误;2. 程序应避免而不捕获的运行时异常;3. 必须捕获的非运行时异常。

5

• 异常类的层次和主要子类: • Error : 一般不能由 java 程序处理,如 jvm 发生错误等• Exception :

1.受检异常:编译能检测到,在程序中必须进行异常处理。(如 I/O 操作)2.非受检异常:编译时不能检测到。称运行时异常 (RuntimeException ) 。 在

程序中可以处理,也可以不处理异常。 (如除 0 )

Object

Throwable

Error Exception

RuntimeException

ArithmeticException 。。。

IOException

6

RuntimeException:可以处理也可以不处理不处理,系统会捕获异常,并停止程序。

ArithmeticException : /0 用 0 取模ArrayIndexOutBoundsException

NullPointerException: 访问空对象

7

9.3 捕获与处理异常在 Java 语言中,异常处理是通过

try 、 catch 、 finally 、 throw 、 throws 五个关键字来实现的。

public class app9_1 { //app9_1.java 异常的产生 public static void main(String args[]) { int i; int a[]={1,2,3,4}; // 定义并初始化数组 for (i=0;i<5;i++) System.out.println( a[i] ); System.out.println( 5/0 ) ; // 运行时异常 }

8

在 Java 的异常处理机制中,提供了 try-catch-finally 语句来捕获和处理一个或多个异常,其语法格式如下:

try{ < 可能产生异常的代码段 > }

catch ( 异常类名 1 对象名 1){ < 异常处理语句序列 1> }catch ( 异常类名 2 对象名 2){ < 异常处理语句序列 2> }…

finally{ < 一定会运行的语句序列 > }

9

public class ExceptionDemo{ public static void main(String args[]){ int a=0; try{ System.out.println(8/a); System.out.println(“ 成功” ); }catch(ArithmeticException e){ System.out.println(e.toString());} finally{ System.out.println(“ 程序结束” );} }} 一定会被

执行

10

class ExceptionDemo1{ // 多 catch public static void main(String args[]){ int n1,n2; String s1,s2; try{ InputStreamReader sr= new InputStreamReader (System.in); BufferedReader br = new BufferedReader( sr); s1 = br.readLine(); // 被除数 s2 = br.readLine(); // 除数 n1 = Integer.parseInt( s1) ; n2 = Integer.parseInt( s2) ; System.out.println( n1/ n2 ); System.out.println(“ 成功” ); } catch(ArithmeticException e){ System.out.println( “ 除数为 0”);} catch(IOException e){ System.out.println( “ 输入异常” ); } finally{ System.out.println(“ 程序结束” );} } }

11

public class app9_2 { // 异常的捕获与处理 public static void main(String args[]) { int a[]={1,2,3,4}; for (int i=0;i<5;i++) { try { System.out.print( (a[i]/i) ); } catch(ArrayIndexOutOfBoundsException e) { System.out.print(“ 捕获到了数组下标越界异

常” ); } catch(ArithmeticException e) { System.out.print(“ 异常类名称是:” +e); // 异常

信息 } catch(Exception e) { System.out.println(“ 捕

获” +e.getMessage() );} finally { System.out.println(“ finally i=”+i); } } System.out.println(“ 继续!!” ); } }

12

程序运行结果为:异常类名称是:java.lang.ArithmeticException:/ by zero finally i=0a[1]/1=2 finally i=1a[2]/2=1 finally i=2a[3]/3=1 finally i=3捕获到了数组下标越界异常 finally i=4继续!!

13

9.4 抛出异常根据异常类的不同,抛出异常的方法也不相同。( 1 )系统自动抛出的异常。( 2 )使用 throw 语句抛出的异常。 throw 由异常类所产生的对象; ( 3 )抛出异常的方法与调用方法处理异常。( 4 )由方法抛出异常交系统处理。

14

( 1 、 2 )程序产生异常 -- throw 语句• 用来明确地由 Java 程序产生一个异常, throw 异常 ;

import java.io.*;public class tryDemo {

public static void main(String args[]){ try{ System.out.println( "1111" ) ;

throw new IOException(" IO error"); }catch( IOException e){

System.out.println( "IO 异常 " ); } finally { System.out.println( "end" ); } } }

15

public class app9_3 { // 使用 throw 语句在方法之中抛出异常

public static void main(String args[]) { int a=5,b=0; try { if (b==0) throw new ArithmeticException(); // 抛出异常 else System.out.println(a+“/“+b+”=”+a/b); } catch(ArithmeticException e) { System.out.println(“ 异常:” +e+” 被抛出

了!” ); } }}

16

( 3 ) 抛出异常的方法与调用方法处理异常。某方法中存在受检异常,但不处理异常,那么必须

交给调用该方法的方法处理: 返回类型 方法名 ( [ 形参 ]) throws ExceptionList{ 方法体 … }

说明:异常可以向上一级调用方法传递ExceptionList 可以多个异常类,用 “ ,” 分隔

void f1{ f2 ();}

void f2{ int a=0; System.out.println(8/a);

}

抛出异常

17

// 转移异常class throwsDemo{ static void fun() throws ArithmeticException { int a=0; System.out.println( 8/a); }

public static void main(String args[ ] ) { try {

fun(); ) catch( ArithmeticException e){ System.out.ptinyln(“ 异常” ); } }}

main

fun

fun() 可以不进行错误处理吗?

18

// 程序产生异常 2

class throwsDemo {

static void fun() throws IOException {

throw new IOException(" IO error");

}

public static void main(String args[]){

try{

fun();

}catch( IOException e){

System.out.println( e.toString() ); }

} }

19

class throwsDemo{ // 转移异常 void input( ) throws IOException {

InputStreamReader sr ;

sr = new InputStreamReader (System.in );

BufferedReader br = new BufferedReader( sr);

String l1;

l1 = br.readLine();

}

public static void main(String args[ ] ) {

try { input();

) catch( IOException e){

System.out.ptinyln(“ 异常” ); }

}

}

20

9.5 自定义异常类创建用户自定义异常时,一般需完成如下的工作。( 1 )声明一个新的异常类,用户自定义的异常

类必须是 Throwable 类的直接或间接子类。( 2 )为用户自定义的异常类定义属性和方法,

或重载父类的属性和方法,使这些属性和方法能够体现该类所对应的错误信息。

用户自定义异常不可能依靠系统自动抛出,而必须借助于 throw 语句来定义何种情况算是产生了此种异常对应的错误,并应该抛出这个异常类的新对象。

21

1 、用户自定义的异常类:• 继承 Exception 类或 Exception 的子类

2 、使用//1 定义自己的异常类class MyException extends Exception {

private int exceptionNo ; // 错误编号 MyException(int a){ exceptionNo = a;}

public String toString() {

if (exceptionNo==1)

return “ 数值小于 0 或大于 100 ,错误号:” +exceptionNo;

else if ( exceptionNo==2)

return “ 信号不能为蓝色,错误号:” +exceptionNo;

}

}

22

//2 使用自定义异常类 class ThrowsDemo{ static void input( int a) throws MyException { if ( a<0 || a>100 ) throw new MyException( 1 ); // 产生异常}

public static void main(String args[ ] ) { try {

input( 120 ); } catch(MyTestException e){ System.out.ptinyln( e ); } }}

23

二 转移异常 – 层层向上传递// 异常从底层向上传递class exceptionDemo { static void f1() throws IOException { throw new IOException(“ 模拟 IO 错 !"); } static void f2() throws IOException { f1(); } public static void main(String args[]){ try{ f2(); }catch( IOException e){ System.out.println( e.toString() ); } }

f1 抛出异常

f2抛出异常

main 处理异常

调用

调用 异常

异常

24

class throwsDemo{ //练习 1 :写出程序的执行结果 static void fun( int x ) throws ArrayIndexOutOfBoundsException , IOException { if (x <=0 ) throw new ArrayIndexOutOfBoundsException(); else if (x>100) throw new IOException(); System.out.println( x ); } public static void main(String args[ ] ) { try {

fun(2 ); fun (0 ); fun (103) ; System.out.println(“ step1 ”); ) catch(ArrayIndexOutOfBoundsException e){ System.out.ptinyln(“ 算术异常” ); } catch( IOException e){ System.out.ptinyln(“IO 异常” ); } finally { System.out.println(“ step2”); } System.out.println(“ program end ”); }}

25

练习 2 :编写程序,从键盘输入一个字母,然后输出它的大

写字母。(程序不用 try ..catch 捕获错误,而是转移异常,

由 main 函数处理异常)

3 编写一个程序,从键盘读入一个被除数,一个除数,然后输出此两个数的商。

注意:需要捕获的错误类型。

26

练习 4:

定义一个类 MyMath 类, 有类方法 int fact(int n) , 计算 n 的阶乘,当参数为负时,抛出一个异常 MyFactException 。当参数超过 30 时,抛出一个异常 MyFactException 。

1) 写出自定义的异常类 MyFactException

2) 写出 MyMath 类及方法 fact 。3) 写出测试代码 , 计算 -5 , 8, 33 的阶乘。

27

练习 5:

给 Math.sqrt( ) 一个负的参数, Java 输出Double.NaN, 现定义一个类 MyMath 类,其中有类方法 mySqrt , 也是计算平方根,但当参数为负时,抛出一个异常 MySqrtException 。

1) 写出自定义的异常类 MySqrtException

2) 写出 MyMath 类及方法 mySqrt 。 ( mySqrt 调用 Math.sqrt)

3) 写出测试代码 , 计算 100 , -30 的平方根。

28

class MySqrtException extends Exception{ MySqrtException() { super( “负数不能开平方根!” ) ; }}class MyMath { static double mySqrt( double data) throws

MySqrtException { if (data<0) throw new MySqrtException(); return (Math.sqrt(data) ) ; }}class Test { public static void main(String args[ ] ){ try { System.out.println( MyMath.mySqrt( 9) ); System.out.println( MyMath.mySqrt( -4) ); } catch( MySqrtException e ){ System.out.println( e) ; } }}

29

class MyFactException extends Exception{ private int errorNo; MyFactException(String s , int _eno){ super( s) ; errorNo = _eno ; } int getErrorNo(){ return errorNo ; } }class MyMath { static int fact( int n) throws MyFactException { int M=1; if (n<0) throw new MyFactException(“n 不能小于 0 !” ,-

1); if (n>30) throw new MyFactException(“n 不能大于 30 !” ,-2);

for (int i=1;i<=n;i++){ M *=i ; return (M) ; }}class Test { public static void main(String args[ ] ){ try { System.out.println( MyMath.fact( -2) ); } catch( MyFactException e ){ System.out.println( e) ; } }}

30

class MyFactException extends Exception{ //2 private int errorNo; MyFactException(int _eno){ errorNo = _eno ; } public String toString(){ if (errorNo== -1) return "n 不能小于 0 ! " ; else if(errorNo == -2) return "n 不能大于 30 ! " ; return "n 不符要求 "; } int getErrorNo(){ return errorNo ; } }class MyMath { static int fact( int n) throws MyFactException { int M=1; if (n<0) throw new MyFactException( -1); if (n>30) throw new MyFactException(-2); for (int i=1;i<=n;i++) M *=i ; return (M) ; }}class tryDemo { public static void main(String args[ ] ){ try { System.out.println( MyMath.fact( 33) ); } catch( MyFactException e ){ System.out.println( e) ; } } }