/** * 异常的分类 : * 1) 按照严重程度 * 1) Error 严重错误 * 2) Exception 普通异常 * 2) 按照处理要求来分 * 1) 受检异常 : 在程序中必须接受检查和处理的异常 * Exception及其子类(RuntimeException及其子类除外) * 2) 非受检异常 : 在程序中不是必须接受检查和处理的异常 * Error及其子类 (太严重) * RuntimeException及其子类 (太轻微) * 异常的处理 : 适用于所有异常 * 1) 捕获 使用语句try catch finally, 组合法3种, 至少保证要有try,还必须有catch或finally * 2) 抛出 在方法签名中使用throws 可能抛出的异常类型, 在语句块中使用throw 异常对象 真的抛出异常, 产生实质破坏 * 3) 先捕获再抛出 先捕获已知异常, 捕获到以后,再把它包装成为其他自定义异常对象, 再抛出自定义异常对象 * * 处理方式的选择 : * 底层方法 : * 抛出异常或捕获再抛出 * 顶层方法 : * 捕获 * * 补充点 : * 方法覆盖 : 子类重写父类的方法. * 条件 : * 1) 方法签名必须一致 (返回值类型一致, 方法名一致, 参数列表一致[参数类型一致, 个数一致, 顺序一致] * 2) 访问控制修饰符子类大于等于父类 * 3) 子类抛出的受检异常范围小于等于父类 * */ @SuppressWarnings("serial") // 自定义异常, 是受检异常, 是必须对其进行处理的异常 class DevidedByZeroException extends Exception { public DevidedByZeroException(String message) { super(message); } public DevidedByZeroException(Exception cause) { super(cause); } } class ExceptionTest5 { public static int divide(int x, int y) throws DevidedByZeroException { int z = 0; try { // 先尝试执行有可能出现异常的代码 z = x / y; } catch (ArithmeticException e) { // 如果真的出现异常就对其进行包装 // 把系统异常包装为自定义异常, 最终抛出去的是自定义异常对象 throw new DevidedByZeroException(e); } return z; } public static void main(String[] args) { try { int ret = divide(10, 2); System.out.println(ret); ret = divide(10, 0); System.out.println(ret); } catch (DevidedByZeroException e) { System.out.println(e); } System.out.println("main end"); } } class ExceptionTest4 { // throws 后面可以跟多个不同类型的异常, 用以表示此方法有可能抛出多种异常 // throws Exception 可以统一地把任意异常抛出, 使得抛出异常模糊, 不建议使用 public static int divide(int x, int y) throws DevidedByZeroException, NullPointerException { int z = 0; if (y == 0) { // 主动抛出自定义异常, 必须在方法签名中加入抛出声明 throw new DevidedByZeroException("被0除错误"); } z = x / y; return z; } /*声明异常类IlleagalNumberException,用来表示无效数字异常 写一个TestException2类,在其中声明int divide(int m, int n)方法,该方法可抛出IlleagalNumberException异常。 方法的两个参数分别为被除数和除数,返回值为商 如果除数为0,则方法抛出IlleagalNumberException异常 改写main方法,调用divide方法计算商值打印输出,并捕获可能出现的异常。*/ //public static void main(String[] args) throws DevidedByZeroException { // 如果在main中抛出异常, 会导致程序极不稳定 public static void main(String[] args) { System.out.println("main begin"); try { int ret = divide(10, 2); System.out.println(ret); ret = divide(10, 0); System.out.println(ret); } catch (DevidedByZeroException e) { System.out.println(e); } System.out.println("main end"); } } class ExceptionTest3 { // 避免类名冲突 public static int divide(int x, int y) { int z = 0; if (y == 0) { RuntimeException re = new ArithmeticException("除数为0错误"); throw re; // 只有执行了throw语句后, 方法才异常返回, 和return最大的区别在于 它是带着破坏性的 } z = x / y; return z; } public static void main(String[] args) { try { System.out.println(divide(10, 2)); System.out.println(divide(10, 0)); } catch (ArithmeticException e) { System.out.println(e); } System.out.println("main end..."); } } public class ExceptionTest { // 避免类名冲突 @SuppressWarnings("null") public static void main(String[] args) { System.out.println("main begin..."); try { // 包围的代码, 有可能抛出异常的语句 int n = Integer.parseInt(args[0]); // 一旦出现异常, 后面的语句没有机会执行, 程序崩溃, 提前结束!! System.out.println("接收到命令行参数的整数:" + n); try { int[] arr = null; System.out.println(arr.length); } catch (Exception e) { System.out.println(e); } System.out.println("after inner try"); return; //} catch (捕获到的异常类型 异常对象) {异常的处理代码} } catch (ArrayIndexOutOfBoundsException e) { // 如果真的捕获到指定类型的异常对象进入这里 e.printStackTrace(); // 打印异常对象出现的栈踪迹 } catch (NumberFormatException e) { System.out.println(e.getMessage()); // 打印异常对象的详细信息 } catch (Exception e) { // 万能夹, 可以捕获任意的其他异常 System.out.println("其他任意可能出现的异常:" + e); } finally { // 最终地, 末了地... 甚至可以在return语句后执行,截获return System.out.println("这句话总是会被打印, 无论前面发生了什么!!!, 都不能拦阻"); // 通常会执行一些关闭和操作系统相关的资源的操作. GC只能关闭在GC区中的资源 } System.out.println("main end..."); // 程序关键代码 } } class ExceptionTest2 { // 避免类名冲突 public static void main(String[] args) { try { Integer.parseInt(args[0]); } catch (Exception e) { e.printStackTrace(); } try { Integer.parseInt(args[0]); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("finally"); } try { Integer.parseInt(args[0]); } finally { System.out.println("finally"); } /* catch () { } finally { } */ } } /** * 编写TestException类,在main方法中接收两个命令行参数,将它们转换为整数,并用第一个数除以第二个数,打印结果。 在命令行运行程序,给出两个参数,测试以下情况,观察运行结果: 其中某个参数不是数字 什么都不传入 第二个参数为0 * @author Administrator * */ public class TestException { public static void main(String[] args) { System.out.println("main begin..."); try { int var1 = Integer.parseInt(args[0]); int var2 = Integer.parseInt(args[1]); int var3 = var1 / var2; System.out.println(var1 + "/" + var2 + "=" + var3); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(e); // 相对详细 } catch (NumberFormatException e) { e.printStackTrace(); // 异常的信息最详细的 } catch (ArithmeticException e) { System.out.println(e.getMessage()); // 最不详细 } catch (Exception e) { System.out.println(e); } System.out.println("main end..."); } } /*声明异常类IlleagalNumberException,用来表示无效数字异常*/ @SuppressWarnings("serial") class IlleagalNumberException extends Exception { public IlleagalNumberException(String message) { super(message); } public IlleagalNumberException(Exception cause) { super(cause); } } class TestException3 { public static int divide(int m, int n) throws IlleagalNumberException { try { return m / n; } catch (ArithmeticException e) { throw new IlleagalNumberException(e); } } public static void main(String[] args) { try { int num1 = Integer.parseInt(args[0], 16); int num2 = Integer.parseInt(args[1], 16); int num3 = divide(num1, num2); // 必须对其进行处理 System.out.println(num1 + " / " + num2 + " = " + num3); } catch (NumberFormatException e) { System.out.println(e); } catch (ArrayIndexOutOfBoundsException e) { e.printStackTrace(); } catch (IlleagalNumberException e) { System.out.println(e); } catch (Exception e) { System.out.println("为保万无一失, 添加这个catch, 可以捕获其他任意异常:" + e); } System.out.println("main end"); } } /* * 写一个TestException2类,在其中声明int divide(int m, int n)方法,该方法可抛出IlleagalNumberException异常。 方法的两个参数分别为被除数和除数,返回值为商 如果除数为0,则方法抛出IlleagalNumberException异常 改写main方法,调用divide方法计算商值打印输出,并捕获可能出现的异常。*/ public class TestException2 { public static int divide(int m, int n) throws IlleagalNumberException { int q = 0; if (n == 0) { throw new IlleagalNumberException("除数为0错误!!!"); } q = m / n; return q; } public static void main(String[] args) { try { int num1 = Integer.parseInt(args[0], 16); int num2 = Integer.parseInt(args[1], 16); int num3 = divide(num1, num2); // 必须对其进行处理 System.out.println(num1 + " / " + num2 + " = " + num3); } catch (NumberFormatException e) { System.out.println(e); } catch (ArrayIndexOutOfBoundsException e) { e.printStackTrace(); } catch (IlleagalNumberException e) { System.out.println(e); } catch (Exception e) { System.out.println("为保万无一失, 添加这个catch, 可以捕获其他任意异常:" + e); } System.out.println("main end"); } }