异常处理

异常处理

Java异常有两大类,分别是失控异常和可控异常。失控异常一般指的是错误(java.lang.Error)
和运行时异常(java.lang.RuntimeException)。
可控异常一般指的是检查性异常java.lang.Execption。在别的文档是直接把错误归一类,异常归一类,然后再讨论运行时异常和检查性异常。

Throwable类

Throwable是所有异常的父类,他拥有的主要方法如下:

  • public String getMessage() 在Throwable类中已经初始化,返回异常的详细信息。
  • public Throwable getCause() 返回异常的原因。
  • public String toString() 返回异常尖端描述
  • public void printStackTrace() 将此throwable和他的回溯输出到standard error
  • public StackTraceElement [] getStackTrace() 返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。

捕获或抛出自己的异常类

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
//同一文件中,只准有一个public类
class PassengerIncorrectException extends Exception {
public PassengerIncorrectException(String message) {
super(message);
}
}
public class Vehicle {
private String id;
private String destination;
private int passenger;

public Vehicle(String id, String destination, int passenger)
{
this.id = id;
this.setDestination(destination);
this.setPassenger(passenger);
}

public void way()
{
System.out.println("id: " +this.id + " tele-transmit");
}


//----------------------GETTER/SETTER------------------------
public String getDestination() {
return destination;
}

public void setDestination(String destination) {
this.destination = destination;
}

public int getPassenger() {
return passenger;
}


//捕获异常
public void setPassenger(int passenger) {
try {
if (passenger < 0) {
throw new PassengerIncorrectException("passenger < 0 !!!!");
}
}catch (PassengerIncorrectException e)//必须精确声明异常类
{
System.out.println(e);
e.printStackTrace();
System.exit(1); //让程序退出执行
} finally {
System.out.printf("setPassenger finlay");
}


this.passenger = passenger;
}

//或者抛出异常
public void setPassenger(int passenger) throws PassengerIncorrectException {
if (passenger < 0) {
throw new PassengerIncorrectException("passenger < 0 !!!!");
this.passenger = passenger;
}


public String getId() {
return id;
}
}

  • 在同一文件中,只准有一个public类
  • 异常必须被抛出throws或者被捕获
  • 必须要用try...catch...来捕获抛出的异常
  • 在catch必须精确的声明的异常类,不能用Exception敷衍,如果同时有多个不同异常,可以用多个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
class NbEcaillesIncorrectException extends Exception {
public NbEcaillesIncorrectException() {
super();
}
}

class NbMaxPangolinException extends Exception {
public NbMaxPangolinException() {
super("Le nombre maximal de pangolins est atteint...");
}
}

class NommageException extends Exception {
public NommageException() {
super();
}
}
class CanardException extends Exception {
public CanardException() {
super();
}
}

class PangolinException extends Exception {
public PangolinException() {
super();
}
}

public class TestC {
private static final boolean PANGOLIN_EXCEPTION = false;
private static final boolean NOMMAGE_EXCEPTION = false;
private static final boolean CANARD_EXCEPTION = false;
private static final boolean NBECAILLESINCORRECT_EXCEPTION = false;
private static final boolean NBMAXPANGOLIN_EXCEPTION = true;
private static final boolean ARITHMETIC_EXCEPTION = false;
private static final boolean ILLEGAL_ARGUMENT_EXCEPTION = false;

public static void m1() throws CanardException {
try {
System.out.println("Début de m1()");
m2();
System.out.println("Fin de m1()");
} catch (PangolinException e) {
System.out.println("Exception Pangolin (de m1()).");
}
}

public static void m2() throws PangolinException, CanardException {
try {
System.out.println("Début de m2()");
m3();
System.out.println("Fin de m2()");
} catch (NbMaxPangolinException e) {
System.out.println("Exception nombre max pangolin (de m2()).");
throw new IllegalArgumentException();
} finally {
System.out.println("Finally de m2()");
}
System.out.println("Fin de m2() après le try/catch/finally");
}

public static void m3() throws PangolinException, CanardException,NbMaxPangolinException {
try {
System.out.println("Début de m3()");
if (PANGOLIN_EXCEPTION)
throw new PangolinException();
if (NOMMAGE_EXCEPTION)
throw new NommageException();
if (CANARD_EXCEPTION)
throw new CanardException();
if (NBECAILLESINCORRECT_EXCEPTION)
throw new NbEcaillesIncorrectException();
if (NBMAXPANGOLIN_EXCEPTION)
throw new NbMaxPangolinException();
if (ARITHMETIC_EXCEPTION)
throw new ArithmeticException();
if (ILLEGAL_ARGUMENT_EXCEPTION)
throw new IllegalArgumentException();
System.out.println("Fin de m3()");
} catch (NommageException | NbEcaillesIncorrectException e) {
System.out.println("Exception Nommage (de m3()).");
}
}

public static void main(String[] args) throws CanardException {
System.out.println("Début de la méthode principale");
m1();
System.out.println("Fin de la méthode principale");
}
}

上面是老师给的例子,可以通过修改常量的真值来测试。

  • 抛出的异常会一直回溯,直到被捕捉。异常被处理之后,程序继续运行。
  • 如果抛出的异常最终没有被捕捉,那么程序会被中止。
  • 如果try,catch内没有return语句,那么执行顺序是 try{} catch(){}finally{} return;
  • 如果try,catch内return语句,在return之前,如果finally存在的话,都会先执行finally语句,最后再return。
  • 如果finally中有return语句,那么程序就在finally被返回,所以finally中的return是一定会被return的。
  • 因为在执行finally之前,reutrn语句已经开始执行,所以在finally内修改返回值是无用的(如果finally没return)。

如果发现错误请留言告知,万分感谢。

参考资料


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!