ErrorException

Error是程序无法处理的错误,比如OutOfMemoryErrorThreadDeath等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。此类异常是程序的致命异常,是无法捕获处理的。

Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。 程序中应当尽可能去处理这些异常。

Exception的继承关系

Exception

运行时异常和非运行时异常的区别

运行时异常都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(索引越界异常)等, 这些异常是非检查型异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

非运行时异常是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOExceptionSQLException等以及用户自定义的Exception异常,这些是检查型异常。一般情况下不自定义检查型异常。

内置异常类

非检查性异常

Exception1

检查性异常

Exception2

内置异常方法

Exception3

捕获异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.ep;

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
int[] array = new int[5];
for (int i = 0; i < 5; i ++)
array[i] = i;

Scanner sc = new Scanner(System.in);
int k = sc.nextInt();
int x = sc.nextInt();

try {
array[k] /= x;
} catch (ArithmeticException e) {
System.out.println("除零错误");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组越界");
}
}
}

输入1

1
3 2

输出1

1
2
3
4
5
array[0] = 0
array[1] = 1
array[2] = 2
array[3] = 1
array[4] = 4

输入2

1
2 0

输出2

1
2
3
4
5
6
除零错误
array[0] = 0
array[1] = 1
array[2] = 2
array[3] = 3
array[4] = 4

输入3

1
-1 0

输出3

1
2
3
4
5
6
数组越界
array[0] = 0
array[1] = 1
array[2] = 2
array[3] = 3
array[4] = 4

getMessage()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package org.ep;

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
int[] array = new int[5];
for (int i = 0; i < 5; i ++)
array[i] = i;

Scanner sc = new Scanner(System.in);
int k = sc.nextInt();
int x = sc.nextInt();

try {
array[k] /= x;
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
}
}
}

输入1

1
3 0

输出1

1
/ by zero

输入2

1
-1 2

输出

1
-1

printStackTrace()

printStackTrace()不会终止程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.ep;

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
int[] array = new int[5];
for (int i = 0; i < 5; i ++)
array[i] = i;

Scanner sc = new Scanner(System.in);
int k = sc.nextInt();
int x = sc.nextInt();

try {
array[k] /= x;
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}

System.out.println("运行结束");
}
}

输入

1
3 0

输出

1
2
3
java.lang.ArithmeticException: / by zero
at org.ep.Main.main(Main.java:16)
运行结束

抛出异常

  • throw: 在函数内抛出一个异常。
  • throws:在函数定义时抛出一些可能的异常。

检查型异常必须被捕获或者抛出。

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
import java.io.IOException;
import java.util.Scanner;

public class Main {

private static void foo() throws IOException, NoSuchFieldException {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
if (x == 1)
throw new IOException("找不到文件!!!");
else
throw new NoSuchFieldException("自定义异常");
}

public static void main(String[] args) {
try {
foo();
} catch (IOException e) {
System.out.println("IOException!");
e.printStackTrace();
} catch (NoSuchFieldException e) {
System.out.println("NoSuchFieldException!");
e.printStackTrace();
}
}
}

try-with-resources

JDK7 之后,Java 新增的try-with-resource语法糖来打开资源,并且可以在语句执行完毕后确保每个资源都被自动关闭。

try 用于声明和实例化资源,catch用于处理关闭资源时可能引发的所有异常。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.io.*;

public class Main {

public static void main(String[] args) {
String line;
try (
BufferedReader br = new BufferedReader(new FileReader("input.txt")); //读文件
BufferedWriter bw = new BufferedWriter(new FileWriter("output.txt")); //写文件
) {
while ((line = br.readLine()) != null) {
System.out.println("Line => " + line);
bw.write("copy: " + line + "\n");
}
bw.flush();
} catch (IOException e) {
System.out.println("IOException in try block =>" + e.getMessage());
}
}
}