一、多层异常捕获
1 import javax.swing.*; 2 3 class AboutException { 4 public static void main(String[] a) 5 { 6 int i=1, j=0, k; 7 // k=i/j; 8 9 10 try 11 { 12 13 k = i/j; // Causes division-by-zero exception 14 //throw new Exception("Hello.Exception!"); 15 } 16 17 catch ( ArithmeticException e) 18 { 19 System.out.println("被0除. "+ e.getMessage()); 20 } 21 22 catch (Exception e) 23 { 24 if (e instanceof ArithmeticException) 25 System.out.println("被0除"); 26 else 27 { 28 System.out.println(e.getMessage()); 29 30 } 31 } 32 33 34 finally 35 { 36 JOptionPane.showConfirmDialog(null,"OK"); 37 } 38 39 } 40 }
1.throw语句抛出异常对象
2.允许运行期间判断某条件是否满足,不满足则抛出AssertionError.
3.启用assert功能
二、多层异常捕获
public class CatchWho2 { public static void main(String[] args) { try { try { throw new ArrayIndexOutOfBoundsException(); } catch(ArithmeticException e) { System.out.println( "ArrayIndexOutOfBoundsException" + "/内层try-catch"); } throw new ArithmeticException(); } catch(ArithmeticException e) { System.out.println("发生ArithmeticException"); } catch(ArrayIndexOutOfBoundsException e) { System.out.println( "ArrayIndexOutOfBoundsException" + "/外层try-catch"); } } }
总结:异常在不同的层次抛出,不同的位置抛出,会导致不同的finally语句块执行
三、finally 语句一定会执行吗?
public class SystemExitAndFinally { public static void main(String[] args) { try{ System.out.println("in main"); throw new Exception("Exception is thrown in main"); //System.exit(0); } catch(Exception e) { System.out.println(e.getMessage()); System.exit(0); } finally { System.out.println("in finally"); } } }
System.exit(0)语句会提前终止程序,所以以上代码不会执行finally语句。
四、如何跟踪异常的传播路径?
// UsingExceptions.java // Demonstrating the getMessage and printStackTrace // methods inherited into all exception classes. public class PrintExceptionStack { public static void main( String args[] ) { try { method1(); } catch ( Exception e ) { System.err.println( e.getMessage() + "\n" ); e.printStackTrace(); } } public static void method1() throws Exception { method2(); } public static void method2() throws Exception { method3(); } public static void method3() throws Exception { throw new Exception( "Exception thrown in method3" ); } }
以上表明:异常的传播路径为:8-16-20-24
五、归纳与总结
1.throw语句抛出异常对象及启用assert功能
2.多层异常捕获时语句的执行顺序以及如何判断语句的执行顺序
3.传播异常的跟踪:对象e.getMassage()及e.printStackTrace()的调用
1 package Exception; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 6 public class TestThrows { 7 8 public static void main(String[] args) { 9 // TODO 自动生成的方法存根 10 FileInputStream fis = new FileInputStream("a.txt"); 11 } 12 }
对比于
1 package Exception; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 6 public class TestThrows { 7 8 public static void main(String[] args) throws FileNotFoundException 9 { 10 // TODO 自动生成的方法存根 11 FileInputStream fis = new FileInputStream("a.txt"); 12 } 13 }
throws语句表明:某方法可能出现某种异常,但他自己不能处理,需要由调用者来处理
六、受控与不受控异常
package Exception; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class CheckedExceptionDemo { public static void main(String[] args) { // TODO 自动生成的方法存根 try{ //抛出受控异常 BufferedReader buf= new BufferedReader(new InputStreamReader(System.in)); System.out.println("请输入整数:"); int input = Integer.parseInt(buf.readLine());//有可能引发运行时异常 System.out.println("input x 10 = " + (input*10)); } //受控异常 catch(IOException e){ System.out.println("I/O错误"); } //非受控异常 catch(NumberFormatException e){ System.out.println("输入必须为整数"); } } }
总结:受控异常需要在catch语句块中声明,而不受控异常不需要
七、子类抛出受控异常的限制
import java.io.*; public class OverrideThrows { public void test()throws IOException { FileInputStream fis = new FileInputStream("a.txt"); } } class Sub extends OverrideThrows { //如果test方法声明抛出了比父类方法更大的异常,比如Exception //则代码将无法编译…… public void test() throws FileNotFoundException { //... } }
总结:一个子类的throws子句抛出的异常,不能是其基类方法的抛出异常对象的父类
八、
九、实际开发中的异常处理
自定义异常与异常处理链
1.自定义异常通常选择直接派生自Exception
Class MyException extends Exception{ .......}
2.在合适的地方使用throw语句抛出自定义异常对象
Class MyClass{ void someMethod(){ if(条件)throw new MyException(); } }
1 /** 2 * 自定义的异常类 3 * @author JinXuLiang 4 * 5 */ 6 class MyException extends Exception 7 { 8 public MyException(String Message) { 9 super(Message); 10 } 11 public MyException(String message, Throwable cause) { 12 super(message, cause); 13 } 14 public MyException( Throwable cause) { 15 super(cause); 16 } 17 18 } 19 20 public class ExceptionLinkInRealWorld { 21 public static void main( String args[] ) 22 { 23 try { 24 throwExceptionMethod(); //有可能抛出异常的方法调用 25 } 26 catch ( MyException e ) 27 { 28 System.err.println( e.getMessage() ); 29 System.err.println(e.getCause().getMessage()); 30 } 31 catch ( Exception e ) 32 { 33 System.err.println( "Exception handled in main" ); 34 } 35 doesNotThrowException(); //不抛出异常的方法调用 36 } 37 38 public static void throwExceptionMethod() throws MyException 39 { 40 41 try { 42 System.out.println( "Method throwException" ); 43 44 throw new Exception("系统运行时引发的特定的异常"); // 产生了一个特定的异常 45 } 46 catch( Exception e ) 47 { 48 System.err.println( 49 "Exception handled in method throwException" ); 50 //转换为一个自定义异常,再抛出 51 throw new MyException("在方法执行时出现异常",e); 52 53 54 } 55 finally { 56 System.err.println( 57 "Finally executed in throwException" ); 58 } 59 60 // any code here would not be reached 61 } 62 63 public static void doesNotThrowException() 64 { 65 try { 66 System.out.println( "Method doesNotThrowException" ); 67 } 68 catch( Exception e ) 69 { 70 System.err.println( e.toString() ); 71 } 72 finally { 73 System.err.println( 74 "Finally executed in doesNotThrowException" ); 75 } 76 77 System.out.println( 78 "End of method doesNotThrowException" ); 79 } 80 }