package example; import javax.swing.*; class AboutException { public static void main(String[] a) { int i=1, j=0, k; // k=i/j; 出现异常 try { //j=0 会出现异常 k = i/j; // Causes division-by-zero exception //throw new Exception("Hello.Exception!"); } catch ( ArithmeticException e) { System.out.println("被0除. "+ e.getMessage()); } catch (Exception e) { //出现异常的运算条件时 if (e instanceof ArithmeticException) System.out.println("被0除"); //执行 else { System.out.println(e.getMessage()); //不执行 } } //出现异常还是没出现异常,都不会影响到finally语句的执行。 //只有一种情况会阻止finally语句的执行,就是JVM被关闭 finally { JOptionPane.showConfirmDialog(null,"OK"); } } }
Java中的异常捕获语句:
Try{
//可能发生运行错误的代码;
}
catch(异常类型 异常对象引用){
//用于处理异常的代码
}
finally{
//用于“善后” 的代码
}
package example; public class CatchWho { public static void main(String[] args) { try { try { throw new ArrayIndexOutOfBoundsException(); } catch(ArrayIndexOutOfBoundsException 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"); } } }
package example; 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"); //执行 } } }
package example; public class EmbededFinally { public static void main(String args[]) { int result; try { System.out.println("in Level 1"); try { System.out.println("in Level 2"); //result=100/0; //Level 2.0 try { System.out.println("in Level 3"); // result=100/0; //Level 3 } catch (Exception e) { System.out.println("Level 3:" + e.getClass().toString()); } finally { } System.out.println("In Level 3 finally"); // result=100/0; //Level 2 } catch (Exception e) { System.out.println("Level 2:" + e.getClass().toString()); } finally { System.out.println("In Level 2 finally"); } result = 100 / 0; //level 1 } catch (Exception e) { System.out.println("Level 1:" + e.getClass().toString()); } finally { System.out.println("In Level 1 finally"); } } }
执行Level 1:
执行Level 2:
执行Level 2.0:
执行Level 3:
通过对上述案例进行分析,可以总结出java多层嵌套异常处理的基本流程:
Try语句可以被嵌套。一个try语句可以在另一个try块内部。每次进入try语句,异常的前后关系都会被推入堆栈。如果一个内部的try语句不含特殊异常的catch处理程序,堆栈将弹出,下一个try语句的catch处理程序将检查是否与之匹配。这个过程将继续直到一个catch语句匹配成功,或者是直到所有的嵌套try语句被检查耗尽。如果没有catch语句匹配,Java的运行时系统将处理这个异常。
package example; import java.io.*; public class CheckedExceptionDemo { public static void main(String[] args) { try { BufferedReader buf = new BufferedReader( new InputStreamReader(System.in)); //抛出受控的异常 System.out.print("请输入整数: "); 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语句的运行结果:
如果输入非整数(代码不变):
如果没有第二处的catch语句输入非整数:
package example; 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"); } } }
结论:finally 不一定会执行,在jvm被关闭的情况下
package example; // 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" ); } }
方法:
printStackTrace:打印方法调用堆栈。
message:每个Throwable类的对象都有一个getMessage方法,它返回一个字串,这个字串是在Exception构造函数中传入的,通常让这一字串包含特定异常的相关信息。
抛出多个受控异常的方法:
package example; import java.io.*; public class ThrowMultiExceptionsDemo { public static void main(String[] args) { try { throwsTest(); } catch(IOException e) { System.out.println("捕捉异常"); } } //抛出多个异常 private static void throwsTest() throws ArithmeticException,IOException { System.out.println("这只是一个测试"); // 程序处理过程假设发生异常 throw new IOException(); //throw new ArithmeticException(); } }
结论:当一个方法声明抛出多个异常时,在此方发出调用语句处只要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子句抛出的异常,不能是其基类同名方法抛出的异常对象的父类。
package example; //异常处理代码模板 /** * 自定义的异常类 * @author JinXuLiang * */ class MyException extends Exception { //构造方法 public MyException(String Message) { super(Message); } public MyException(String message, Throwable cause) { super(message, cause); } public MyException( Throwable cause) { super(cause); } } public class ExceptionLinkInRealWorld { public static void main( String args[] ) { try { throwExceptionMethod(); //有可能抛出异常的方法调用 } catch ( MyException e ) { System.err.println( e.getMessage() ); System.err.println(e.getCause().getMessage()); } catch ( Exception e ) { System.err.println( "Exception handled in main" ); } doesNotThrowException(); //不抛出异常的方法调用 } public static void throwExceptionMethod() throws MyException { try { System.out.println( "Method throwException" ); throw new Exception("系统运行时引发的特定的异常"); // 产生了一个特定的异常 } catch( Exception e ) { System.err.println( "Exception handled in method throwException" ); //转换为一个自定义异常,再抛出 throw new MyException("在方法执行时出现异常",e); } finally { System.err.println( "Finally executed in throwException" ); } // any code here would not be reached } public static void doesNotThrowException() { try { System.out.println( "Method doesNotThrowException" ); } catch( Exception e ) { System.err.println( e.toString() ); } finally { System.err.println( "Finally executed in doesNotThrowException" ); } System.out.println( "End of method doesNotThrowException" ); } }