Error
与Exception
Error
是程序无法处理的错误,比如OutOfMemoryError
、ThreadDeath
等。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。此类异常是程序的致命异常,是无法捕获处理的。
Exception
是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。 程序中应当尽可能去处理这些异常。
Exception
的继承关系
运行时异常和非运行时异常的区别
运行时异常都是RuntimeException
类及其子类异常,如NullPointerException
(空指针异常)、IndexOutOfBoundsException
(索引越界异常)等, 这些异常是非检查型异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。
非运行时异常是RuntimeException
以外的异常,类型上都属于Exception
类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException
、SQLException
等以及用户自定义的Exception
异常,这些是检查型异常。一般情况下不自定义检查型异常。
内置异常类
非检查性异常
检查性异常
内置异常方法
捕获异常
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
1 2 3 4 5
| array[0] = 0 array[1] = 1 array[2] = 2 array[3] = 1 array[4] = 4
|
输入2
输出2
1 2 3 4 5 6
| 除零错误 array[0] = 0 array[1] = 1 array[2] = 2 array[3] = 3 array[4] = 4
|
输入3
输出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
输入2
输出
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 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()); } } }
|