异常处理
异常分类
异常对象都是派生于Throwable类的一个实例
异常结构
-
Throwable
- Error
- Exception
- IOException
- RuntimeException
-
派生于Error和RuntimeException的称为非受查异常,其他的称为受查异常
// 顶层异常类
public class Throwable implements Serializable {}
// Java运行时系统内部错误和资源耗尽
public class Error extends Throwable {}
// 异常
public class Exception extends Throwable {}
// 运行时异常
public class RuntimeException extends Exception {}
// IO异常
public class IOException extends Exception {}
- 常见Exception
EOFException
FileNotFoundException
IOException
ClassNotFoundException
NoSuchFieldException
NoSuchMethodException
ReflectiveOperationException
RuntimeException
- 常见RuntimeException
ArithmeticException.java
ArrayIndexOutOfBoundsException.java
ArrayStoreException.java
ClassCastException.java
EnumConstantNotPresentException.java
IllegalArgumentException.java
IllegalMonitorStateException.java
IllegalStateException.java
IllegalThreadStateException.java
IndexOutOfBoundsException.java
NegativeArraySizeException.java
NullPointerException.java
NumberFormatException.java
SecurityException.java
StringIndexOutOfBoundsException.java
TypeNotPresentException.java
UnsupportedOperationException.java
- 子类抛出的异常不能比父类更通用
- 声明异常使用throws
public FileInputStream(File file) throws FileNotFoundException {}
- 抛出异常使用throw
throw new NullPointerException();
创建异常类
- 应该包含无参构造和带有详细信息的参数构造器
public class ExceptionDemo1 extends Exception {
public ExceptionDemo1() {
}
// 能够打印详细信息
public ExceptionDemo1(String message) {
super(message);
}
}
捕获异常
try {
// error
} catch() {
// process error
}
抛出异常和异常链
- 抛出原始异常,可以使用initCause设置
- 获取原始异常getCause
public static void main(String[] args) {
try {
b();
} catch (Throwable e) {
System.out.println("error = " + e.getMessage());
System.out.println("init cause = " + e.getCause());
}
}
public static void a() {
throw new NullPointerException();
}
public static void b() throws Throwable {
try {
a();
} catch (Exception e) {
Throwable th = new Exception("b methods error");
// 将e设置为原始异常
th.initCause(e);
// 等同于
// Throwable th = new Exception("b methods error", e);
throw th;
}
}
finally
- 最终一定会被执行的代码块
try {
} catch() {
} finally {
}
- finally出现return时,try块的返回无效,因为finally是一定会被执行的,在try中return前就已经执行,所以先返回
public static void main(String[] args) {
System.out.println(a()); // 2
}
static int a() {
try {
return 1;
} finally {
return 2;
}
}
try-with-resource
- try块退出时,会自动调用close方法
public static void main(String[] args) {
try (FileInputStream in = new FileInputStream("");
FileOutputStream out = new FileOutputStream("")) {
} catch (Exception e) {
}
}
堆栈轨迹元素
- 打印异常堆栈printStackTrace
- 获取堆栈数组信息getStackTrace
public static void main(String[] args) {
try {
a();
} catch (Exception e) {
e.printStackTrace();
System.out.println("--------------");
StackTraceElement[] stackTrace = e.getStackTrace();
Stream.of(stackTrace).forEach(System.out::println);
}
}
static void a() {
throw new NullPointerException();
}
java.lang.NullPointerException
at com.java.practice.exception.ExceptionDemo4.a(ExceptionDemo4.java:26)
at com.java.practice.exception.ExceptionDemo4.main(ExceptionDemo4.java:16)
--------------
com.java.practice.exception.ExceptionDemo4.a(ExceptionDemo4.java:26)
com.java.practice.exception.ExceptionDemo4.main(ExceptionDemo4.java:16)