第 9 章 异常处理
-
Upload
dingbang-lio -
Category
Documents
-
view
124 -
download
0
description
Transcript of 第 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) ; } } }