1 package cn.temptation;
2
3 public class Sample01 {
4 public static void main(String[] args) {
5 /*
6 * 异常:Java程序在运行过程中出现的错误
7 *
8 * 类 Throwable:Java 语言中所有错误或异常的超类。
9 * 只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。
10 * 类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。
11 *
12 * 类 Error:Error 是 Throwable 的子类,用于指示合理的应用程序不应该试图捕获的严重问题。
13 * 大多数这样的错误都是异常条件。虽然 ThreadDeath 错误是一个“正规”的条件,但它也是 Error 的子类,因为大多数应用程序都不应该试图捕获它。
14 *
15 * 类 Exception:Exception 类及其子类是 Throwable 的一种形式,它指出了合理的应用程序想要捕获的条件。
16 *
17 * 异常的分类:
18 * 1、编译时异常:Exception类中除去RuntimeException及其子类以外其他的
19 * 2、运行时异常:RuntimeException及其子类
20 *
21 * 异常的处理方式:
22 * 1、try...catch...finally格式及其变体
23 * 2、throws/throw
24 *
25 * try...catch...finally处理方式:
26 * try {
27 * 可能出现问题的代码
28 * } catch(异常名称 变量) {
29 * 针对问题的处理
30 * } finally {
31 * 释放资源等操作
32 * }
33 *
34 * try...catch...finally处理的变体方式:
35 * try {
36 * 可能出现问题的代码
37 * } catch(异常名称 变量) {
38 * 针对问题的处理
39 * }
40 */
41
42 // 下句语句编译阶段无语法错误,但是执行时产生异常,这个异常不是由开发人员来处理,应该由开发人员编写代码时就进行判断处理
43 // System.out.println(2 / 0);
44
45 // 【针对单个异常】
46 // try {
47 // System.out.println(2 / 0);
48 // } catch (ArithmeticException e) {
49 // System.out.println("除数不能为0");
50 // }
51
52 // 【针对多个异常】
53 int[] arr = { 1, 2, 3 };
54
55 // try {
56 // // 如果没有进行异常处理,执行时,首先JVM捕获数组越界异常
57 // System.out.println(arr[3]);
58 // System.out.println(2 / 0);
59 // } catch (ArrayIndexOutOfBoundsException e) {
60 // System.out.println("数组的索引越界");
61 // } catch (ArithmeticException e) {
62 // System.out.println("除数不能为0");
63 // }
64
65 // 上述的异常处理代码会显示"数组的索引越界",因为代码的顺序执行,首先捕获到索引越界异常,如果解决掉这个问题,再执行会捕获到除数为0的异常
66
67 // try {
68 // System.out.println(arr[3]);
69 // System.out.println(2 / 0);
70 // } catch (Exception e) {
71 // System.out.println("代码有问题");
72 // }
73
74 // 上述的异常处理代码使用异常基类Exception类,这样不用明确指出是哪一种异常(偷懒写法)
75
76 // 【JDK 1.7之后开始支持的语法】
77 try {
78 System.out.println(arr[3]);
79 System.out.println(2 / 0);
80 } catch (ArrayIndexOutOfBoundsException | ArithmeticException e) {
81 System.out.println("代码有问题");
82 }
83
84 // 上述的异常处理代码需要多个异常是针对同一类类型的问题,否则无法明确具体是什么异常
85 }
86 }
1 package cn.temptation;
2
3 public class Sample02 {
4 public static void main(String[] args) {
5 /*
6 * 对异常的两种处理方式的理解:
7 * 类比生病
8 * 1、哪里有病了哪里疼痛,直接就在对应的问题就发现问题
9 * 2、有病的地方并不是病因产生的地方,而是病状呈现的地方,也就是问题不断抛出最后得到的结果
10 */
11
12 // try...catch...finally处理时的注意问题:
13 // 1、同时使用父类异常 和 子类异常时,父类异常不能写在子类异常之前,否则有语法错误
14 // try {
15 // System.out.println(2 / 0);
16 // } catch (Exception e) {
17 // System.out.println("代码有问题");
18 // } catch (ArithmeticException e) {
19 // // 语法错误:Unreachable catch block for ArithmeticException. It is already handled by the catch block for Exception
20 // System.out.println("除数不能为0");
21 // }
22
23 // 下面语句执行时显示子类异常信息
24 try {
25 System.out.println(2 / 0);
26 } catch (ArithmeticException e) {
27 // 语法错误:Unreachable catch block for ArithmeticException. It is already handled by the catch block for Exception
28 System.out.println("除数不能为0");
29 } catch (Exception e) {
30 System.out.println("代码有问题");
31 }
32 }
33 }
1 package cn.temptation;
2
3 public class Sample03 {
4 public static void main(String[] args) {
5 /*
6 * Throwable类的常用成员方法:
7 * 1、String getMessage() :返回此 throwable 的详细消息字符串。
8 * 2、String toString() :返回此 throwable 的简短描述。
9 * 3、void printStackTrace() :将此 throwable 及其追踪输出至标准错误流。
10 */
11
12 try {
13 System.out.println(2 / 0);
14 } catch (Exception e) {
15 System.out.println(e.getMessage()); // / by zero
16 System.out.println(e.toString()); // java.lang.ArithmeticException: / by zero
17 e.printStackTrace(); // java.lang.ArithmeticException: / by zero at cn.temptation.Sample03.main(Sample03.java:13)
18 }
19 }
20 }
1 package cn.temptation;
2
3 public class Sample04 {
4 public static void main(String[] args) {
5 /*
6 * throws 关键字的使用:
7 * 定义方法时,使用throws关键字标记需要暴露出来被开发人员处理的问题
8 */
9
10 // 下句语句对calc方法的调用,因为在主函数中没有对calc方法抛出的异常进行处理,所以异常还是由jvm进行捕获
11 // 调用calc方法,收到其抛出的异常,没有进行处理
12 // calc();
13
14 try {
15 // 调用calc方法,收到其抛出的异常,并进行处理
16 calc();
17 } catch (ArithmeticException e) {
18 System.out.println("除数不为0");
19 }
20 }
21
22 // 在方法内部对异常不进行处理,在方法的声明上通过throws标记需要处理的异常,并向外抛出
23 // 定义计算方法
24 public static void calc() throws ArithmeticException {
25 System.out.println(2 / 0);
26 }
27 }
1 package cn.temptation;
2
3 public class Sample05 {
4 public static void main(String[] args) {
5 /*
6 * throw关键字的使用:
7 * 用在方法内部,出现某种情况程序无法继续运行时,需要进行跳转通过throw把异常对象进行抛出
8 *
9 *
10 * throws 和 throw 的区别:
11 * 1、throws
12 * A:用在方法声明中,后面是异常类名
13 * B:throws后可以有多个异常类名,之间使用英文逗号分隔
14 * C:表示抛出异常,由方法的调用者进行处理
15 * D:throws表示出现异常的可能,不一定会发生这些异常
16 *
17 * 2、throw
18 * A:用在方法内,后面是异常类的对象
19 * B:throw后只能抛出一个异常对象
20 * C:表示抛出异常,由方法内的语句处理,方法被调用时,调用方法处进行捕获处理
21 * D:throw表示抛出异常,执行throw一定是抛出了某种异常
22 */
23
24 // 使用throw关键字,在方法中抛出异常的实例对象,方法调用时没有语法错误
25 // calc();
26
27 // 下面代码捕获到ArithmeticException异常,并执行catch代码块的处理
28 // try {
29 // calc();
30 // } catch (ArithmeticException e) {
31 // System.out.println("计算异常");
32 // }
33
34 // 方法声明上throws出的异常 和 方法内throw出的异常是父子关系,必须进行异常处理,否则就语法出错
35 // method1();
36
37 // try {
38 // method1();
39 // } catch (Exception e) {
40 // System.out.println("除数不为0");
41 // }
42
43 // 方法声明上throws出的异常 和 方法内throw出的异常同级且不相同,以throw出的异常为准
44 method2();
45 }
46
47 // 声明计算方法
48 public static void calc() {
49 int i = 2;
50 int j = 0;
51
52 if (j == 0) { // 判断除数是0
53 throw new ArithmeticException();
54 } else {
55 System.out.println(i / j);
56 }
57 }
58
59 public static void method1() throws Exception {
60 int i = 2;
61 int j = 0;
62
63 if (j == 0) { // 判断除数是0
64 throw new ArithmeticException();
65 } else {
66 System.out.println(i / j);
67 }
68 }
69
70 public static void method2() throws ArrayIndexOutOfBoundsException {
71 int i = 2;
72 int j = 0;
73
74 if (j == 0) { // 判断除数是0
75 throw new ArithmeticException();
76 } else {
77 System.out.println(i / j);
78 }
79 }
80 }
1 package cn.temptation;
2
3 public class Sample06 {
4 public static void main(String[] args) {
5 /*
6 * 两种异常处理方式的选择:
7 * 1、如果在方法内部进行处理,选择try...catch...finally结构
8 * 2、如果在方法外部进行处理,选择throws/throw
9 *
10 * finally的特点:finally中的语句一定会被执行
11 * 注意:在执行finally语句块之前虚拟机终止了,那么finally语句块中的语句不会执行
12 */
13
14 try {
15 System.out.println(2 / 0);
16 } catch (Exception e) {
17 System.out.println("异常处理");
18 /*
19 * System类的常用成员方法:
20 * static void exit(int status) :终止当前正在运行的 Java 虚拟机。
21 */
22 System.exit(0);
23 } finally {
24 System.out.println("finally中的语句一定会被执行");
25 }
26 }
27 }
1 package cn.temptation;
2
3 public class Sample07 {
4 public static void main(String[] args) {
5 // 在try...catch...finally...结构中使用return的问题:
6 // 1、catch语句块中有return语句,finally语句块中没有return语句,执行顺序为:
7 // 先执行catch语句块中return语句之前的语句,再执行finally语句块中的语句,最后执行catch中的return语句,显示结果为4
8 // 2、catch语句块中有return语句,finally语句块中也有return语句,执行顺序为:
9 // 先执行catch语句块中return语句之前的语句,再执行catch中的return语句,然后执行finally语句块中的语句,最后执行finally语句块中的return语句,显示结果为5
10 System.out.println(show());
11 }
12
13 public static int show() {
14 try {
15 System.out.println(2 / 0);
16 return 3;
17 } catch (Exception e) {
18 System.out.println("异常处理");
19 return 4;
20 } finally {
21 System.out.println("finally中的语句");
22 return 5;
23 }
24 }
25 }
1 package cn.temptation;
2
3 public class Sample08 {
4 public static void main(String[] args) {
5 // try...catch...finally...形式
6 // 完整形式
7 try {
8
9 } catch (Exception e) {
10
11 } finally {
12
13 }
14
15 // try...catch..(单个异常)
16 try {
17
18 } catch (Exception e) {
19
20 }
21
22 // try...catch..(多个异常)
23 try {
24
25 } catch (ArithmeticException e) {
26
27 } catch (Exception e) {
28
29 }
30
31 // try...finally...
32 // 没有catch代码块结构语法也正确,这种形式目的是为了使用后释放资源
33 try {
34
35 } finally {
36
37 }
38
39 // 语法错误
40 // try {
41 //
42 // }
43
44 // 语法错误
45 // catch (Exception e) {
46 //
47 // }
48
49 // 语法错误
50 // catch (Exception e) {
51 //
52 // } finally {
53 //
54 // }
55
56 // 语法错误
57 // finally {
58 //
59 // }
60 }
61 }
1 package cn.temptation;
2
3 public class Sample09 {
4 public static void main(String[] args) {
5 // 自定义异常类
6 try {
7 show(200);
8 } catch (TestException e) {
9 e.printStackTrace();
10 }
11 }
12
13 public static void show(int age) throws TestException {
14 if (age < 0 || age > 150) {
15 throw new TestException("年龄错误!");
16 } else {
17 System.out.println("年龄为:" + age);
18 }
19 }
20 }
21
22 /**
23 * 自定义异常类
24 */
25 class TestException extends Exception {
26 // 构造函数
27 public TestException() {
28
29 }
30
31 public TestException(String msg) {
32 super(msg);
33 }
34 }