Java异常Exception

捕获异常时需要注意 try、catch、finally 块中的控制转移语句。示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
public class TryCatchFinallySample {

private static int testFinallyReturn() {
int i = 1;
try {
return i;
} catch (Exception e) {
return i;
} finally {
return 2;
}
}

private static Page testReferenceReturn() {
Page page = new Page(1, 10);
try {
// 返回的过程:先给返回值赋值,然后调用finally代码块,最后才是返回到try中的return语句
return page;
} catch (Exception e) {
return page;
} finally {
// 修改引用类型变量指向对象的值
page.setCurrent(2);
page.setSize(20);
}
}

private static Page testReferenceNewReturn() {
Page page = new Page(1, 10);
try {
// return的返回值暂存区存的是引用类型
return page;
} catch (Exception e) {
return page;
} finally {
// 使用new之后page指向了新的Page对象,并未改变暂存区的引用类型变量的指向,引用类型变量的定义类似于指针
page = new Page(2, 20);
}
}

private static int testCatchReturn() {
int i = 1;
try {
throw new RuntimeException("oh no!");
} catch (Exception e) {
return i;
} finally {
return 2;
}
}

private static int testValueReturn() {
int i = 1;
try {
return i;
} catch (Exception e) {
return i;
} finally {
// 值传递,在finally里修改返回值也不会改变实际的返回值
i = 2;
}
}


static class Page {
private int current;
private int size;

public Page(int current, int size) {
this.current = current;
this.size = size;
}

public int getCurrent() {
return current;
}

public void setCurrent(int current) {
this.current = current;
}

public int getSize() {
return size;
}

public void setSize(int size) {
this.size = size;
}

@Override
public String toString() {
return "Page{" +
"current=" + current +
", size=" + size +
'}';
}
}

/**
* 测试结论:finally中存在控制转移语句(return、break、continue)时会优先于try、catch中的控制转移语句。
* 原因是finally块中的代码会插入到try或者catch的return语句之前。
*/
public static void main(String[] args) {
System.out.println("值传递时的原返回值:1,引用传递时的原返回值:Page{current=1, size=10}");
System.out.println("测试finally中包含return语句:" + testFinallyReturn());
System.out.println("值传递时,finally修改返回值:" + testValueReturn());
System.out.println("引用传递时,finally修改返回值:" + testReferenceReturn());
System.out.println("引用传递时,finally返回new的引用对象:" + testReferenceNewReturn());
System.out.println("测试catch块进行return:" + testCatchReturn());
}
}

运行结果:

1
2
3
4
5
6
值传递时的原返回值:1,引用传递时的原返回值:Page{current=1, size=10}
测试finally中包含return语句:2
值传递时,finally修改返回值:1
引用传递时,finally修改返回值:Page{current=2, size=20}
引用传递时,finally返回new的引用对象:Page{current=1, size=10}
测试catch块进行return:2