King's Studio

Java中的异常处理

字数统计: 1.2k阅读时长: 5 min
2019/01/26 Share

今天总结一下Java中的异常和处理机制,首先我们知道Error类和Exception类都是Throwable的子类,Error类以及它子类的实例,代表了JVM本身的错误,程序员无法通过代码处理,因此我们需要去关注Exception类以及它的子类。异常通常可以分为两类,一类是unckecked exception,这类异常在编译时不会提示,通常是代码本身的问题,如除0异常ArithmeticException,数组下标越界ArrayIndexOutOfBoundsException,空指针NullPointerException等。

unckecked exception

1
2
3
4
5
6
public class Untitled {
public static void main(String[] args) {
int i = 1/0;
System.out.println(i);
}
}

这类异常在编译时能够通过,但是运行时会提示错误,诸如此类代码需要程序员自己去进行修改。运行时会提示如下:

1
2
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Untitled.main(Untitled.java:4)

另一类是checked exception,这是除了Error和RuntimeException的其它异常,这类异常强制要求程序员做处理,否则编译不能通过,这样的异常一般是由程序的运行环境导致的,如SQLException,IOException,ClassNotFoundException等。

checked exception

对于checked exception,有两种不同的处理方式:1、使用try…catch…finally语句块处理它,2、在函数申明时使用throws抛给函数调用者去解决。

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
public class ReadFileTest {
public static void main(String[] args) {
//因为reader需要重复使用,因此申明在外部
FileReader reader = null;
try {
reader = new FileReader("/Users/jinqi/Desktop/a.txt");
char c = (char) reader.read();
char c2 = (char) reader.read();
System.out.println(""+c+c2);
}catch (FileNotFoundException e) {//子类异常在父类异常之前catch
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally {//一定会执行的代码
try {
if (reader!=null) {//if语句用来判断reader是否为空
reader.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}

下面我们来讲讲try…catch…finally语句块的注意点:一、异常匹配是按照catch块的顺序从上往下寻找的,只有第一个匹配的catch会得到执行。匹配时,不仅运行精确匹配,也支持父类匹配,因此,如果同一个try块下的多个catch异常类型有父子关系,应该将子类异常放在前面,父类异常放在后面,这样保证每个catch块都有存在的意义。二、通常将try、catch、finally三个语句块中都需要用到的变量申明为全局变量,因为可能会重复使用。三、通常try后面必须跟一个catch或finally语句,finally语句块中的代码不管有没有异常,一定执行。

try…catch…finally语句块和return的执行顺序问题

try、catch、finally语句执行顺序:1、try语句中若有异常,进入catch语句捕捉异常,然后执行try语句中剩下的语句,最后进入finally,finally语句块中的内容一定会执行;2、try语句中无异常,try语句块中的语句执行完进入finally;3、如果try语句块中有return,先执行完finally语句,再return。

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
public class TestReadFile {
public static void main(String[] args) {
String str = new TestReadFile().openFile();
System.out.println(str);
}

String openFile() {
try {
System.out.println("aaa");
FileInputStream fis = new FileInputStream("/Users/jinqi/Desktop/a.txt");
int a = fis.read();
System.out.println("bbb");
//执行完finally语句块中的语句之后,再return
return "step1";
} catch (FileNotFoundException e) {
System.out.println("catching!");
e.printStackTrace();
return "step2";
} catch (IOException e) {
e.printStackTrace();
return "step3";
}finally {
System.out.println("finally!");
//return "fff";该语句会覆盖try语句中的return
}
}
}

运行结果如下:

1
2
3
4
aaa
bbb
finally!
step1

由于finally中的return会覆盖try或者catch中的返回值,通常建议:1、不要在finally语句块中不要加return语句;2、不要在finally中抛出异常;3、减轻finally的任务,不要在finally中做一些其它的事情,finally语句块仅仅用来释放资源是最合适的。

申明方法时使用throws

这种方法的具体操作是:定义方法时先抛出所有异常,然后谁调用该方法,谁去具体处理,加try/catch处理问题,调用者需要为可能发生的异常负责。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class TestReadFile {
public static void main(String[] args) {
String str;
//谁调用openFile()方法,谁做具体处理
try {
str = new TestReadFile().openFile();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

//定义方法时抛出异常
String openFile() throws FileNotFoundException,IOException {
FileReader reader = new FileReader("/Users/jinqi/Desktop/a.txt");
char c = (char)reader.read();
System.out.println(c);
return ""+c;
}
}

throw异常抛出语句

程序员也可以通过throw语句手动显式的抛出一个异常,throw语句的后面必须是一个异常对象,throw语句必须写在函数中,执行throw语句的地方就是一个异常抛出点,它和由JRE自动形成的异常抛出点没有任何差别。

1
2
3
4
public void save(User user){
if(user == null)
throw new IllegalArgumentException("User对象为空");
}

原文作者:金奇

原文链接:https://www.rossontheway.com/2019/01/26/java回顾4/

发表日期:January 26th 2019, 12:00:00 am

更新日期:March 21st 2019, 9:34:47 am

版权声明:本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可,除特别声明外,转载请注明出处!

CATALOG
  1. 1. unckecked exception
  2. 2. checked exception
    1. 2.1. try…catch…finally语句块
      1. 2.1.1. try…catch…finally语句块和return的执行顺序问题
    2. 2.2. 申明方法时使用throws
    3. 2.3. throw异常抛出语句