300 likes | 483 Views
第 9 章 异常处理. 教学内容: 异常处理的机制 捕获与处理异常 多异常处理 抛出异常 自定义异常类 重点: 异常处理的机制 捕获与处理异常 难点: 自定义异常类 学时: 3. 9.1 异常处理的基本概念. 9.1.1 错误与异常. 运行错误:系统运行错误和逻辑运行错误。 系统运行错误简称为错误,是指程序在执行过程中所产生对操作系统的损害。 逻辑运行错误是指程序不能实现程序员的设计意图和设计功能而产生的错误,这种错误也被称为异常。. 9.1.2 Java 异常处理机制.
E N D
第9章异常处理 教学内容: 异常处理的机制 捕获与处理异常 多异常处理 抛出异常 自定义异常类 重点: 异常处理的机制 捕获与处理异常 难点: 自定义异常类 学时:3
9.1 异常处理的基本概念 9.1.1 错误与异常 运行错误:系统运行错误和逻辑运行错误。 系统运行错误简称为错误,是指程序在执行过程中所产生对操作系统的损害。 逻辑运行错误是指程序不能实现程序员的设计意图和设计功能而产生的错误,这种错误也被称为异常。
9.1.2 Java异常处理机制 Java异常处理机制,简单地说,就是程序在运行时,发现异常的代码可以“抛出”一个异常,运行系统“捕获”该异常,并交由程序员编写的相应代码进行异常处理。 jvm: 产生异常对象 抛出异常对象 java 程序: 捕获异常(catch) 处理异常 Public class ExceptionDemo{ public static void main(String args[]){ int a=0; System.out.println(8/a); } }
9.2 异常处理类 • Java语言中定义了很多异常类,而每个异常类都代表一种运行错误 • Java的异常类是处理运行时错误的特殊类,类中包含了该运行错误的信息和处理错误的方法等内容。 • 程序对错误与异常的处理方式有三种: • 程序不能处理的错误; • 程序应避免而不捕获的运行时异常; • 必须捕获的非运行时异常。
异常类的层次和主要子类: • Error : 一般不能由java程序处理,如jvm 发生错误等 • Exception: • 受检异常:编译能检测到,在程序中必须进行异常处理。(如I/O操作) • 非受检异常:编译时不能检测到。称运行时异常(RuntimeException )。 在程序中可以处理,也可以不处理异常。 (如除 0) Object Throwable Exception Error RuntimeException IOException ArithmeticException 。。。
RuntimeException: • 可以处理也可以不处理 • 不处理,系统会捕获异常,并停止程序。 • ArithmeticException : /0 用0取模 • ArrayIndexOutBoundsException • NullPointerException:访问空对象
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 ) ; //运行时异常 }
try { <可能产生异常的代码段> } catch (异常类名1 对象名1) { <异常处理语句序列1> } catch (异常类名2 对象名2) { <异常处理语句序列2> } … finally { <一定会运行的语句序列> } 在Java的异常处理机制中,提供了try-catch-finally语句来捕获和处理一个或多个异常,其语法格式如下:
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(“程序结束”);} } } 一定会被执行
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(“程序结束”);} } }
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(“继续!!”); } }
程序运行结果为: 异常类名称是: java.lang.ArithmeticException:/ by zero finally i=0 a[1]/1=2 finally i=1 a[2]/2=1 finally i=2 a[3]/3=1 finally i=3 捕获到了数组下标越界异常 finally i=4 继续!!
9.4 抛出异常 根据异常类的不同,抛出异常的方法也不相同。 (1)系统自动抛出的异常。 (2)使用throw 语句抛出的异常。 throw 由异常类所产生的对象; (3)抛出异常的方法与调用方法处理异常。 (4)由方法抛出异常交系统处理。
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" ); } } } (1、2)程序产生异常 -- throw 语句 • 用来明确地由Java 程序产生一个异常, throw 异常 ;
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+” 被抛出了!”); } } }
void f1{ f2 (); } void f2{ int a=0; System.out.println(8/a); } 抛出异常 (3)抛出异常的方法与调用方法处理异常。 • 某方法中存在受检异常,但不处理异常,那么必须交给调用该方法的方法处理: • 返回类型 方法名( [形参]) throws ExceptionList{ • 方法体 … } • 说明: • 异常可以向上一级调用方法传递 • ExceptionList 可以多个异常类,用 “,”分隔
main //转移异常 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(“异常”); } } } fun fun() 可以不进行错误处理吗?
//程序产生异常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() ); } }}
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(“异常”); } } }
9.5 自定义异常类 创建用户自定义异常时,一般需完成如下的工作。 (1)声明一个新的异常类,用户自定义的异常类必须是Throwable类的直接或间接子类。 (2)为用户自定义的异常类定义属性和方法,或重载父类的属性和方法,使这些属性和方法能够体现该类所对应的错误信息。 用户自定义异常不可能依靠系统自动抛出,而必须借助于throw语句来定义何种情况算是产生了此种异常对应的错误,并应该抛出这个异常类的新对象。
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; } }
//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 ); } } }
main 处理异常 异常 调用 f2 抛出异常 调用 异常 f1 抛出异常 二 转移异常 – 层层向上传递 //异常从底层向上传递 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() ); } }
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 ”); } }
练习2: 编写程序,从键盘输入一个字母,然后输出它的大写字母。 (程序不用 try ..catch 捕获错误,而是转移异常,由main 函数处理异常) 3 编写一个程序,从键盘读入一个被除数,一个除数,然后输出此两个数的商。 注意:需要捕获的错误类型。
练习4: 定义一个类 MyMath 类, 有类方法 int fact(int n) , 计算n的阶乘,当参数为负时,抛出一个异常 MyFactException。当参数超过30时,抛出一个异常 MyFactException。 1) 写出自定义的异常类 MyFactException 2) 写出 MyMath 类及方法 fact 。 3) 写出测试代码,计算 -5,8, 33 的阶乘。
练习5: 给 Math.sqrt( ) 一个负的参数,Java 输出Double.NaN, 现定义一个类 MyMath 类,其中有类方法 mySqrt , 也是计算平方根,但当参数为负时,抛出一个异常 MySqrtException。 1) 写出自定义的异常类 MySqrtException 2) 写出 MyMath 类及方法 mySqrt 。( mySqrt 调用 Math.sqrt) 3) 写出测试代码,计算 100, -30 的平方根。
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) ; } } }
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) ; } } }
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) ; } } }