IDEA 快捷键
双击 shift 弹出查找对话框
try catch
public class ExceptionFirstExpression {
public static void main(String[] args) {
// >> TODO try 语句中如果发生了异常(Exception),那么程序会跳转到catch语句。
// >> TODO Java会将异常相关信息封装在一个异常类的实例中,ex是指向这个异常实例的引用
// >> TODO "处理"最简单的方法,就是调用printStackTrace将异常信息输出到控制台
// >> TODO catch语句执行完毕,程序会继续向下顺序执行
try {
int[] arr = new int[1];
arr[1] = 9;
} catch (Exception ex) {
int abc = 999;
ex.printStackTrace();
}
try {
String str = "";
str.substring(9, 10);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("程序执行结束");
}
}
按照异常的继承关系分类
- 所有异常的父类: Throwable
- 两类异常: Error 和 Exception
Error 平台应该处理的错误,但平台也处理不了
Exception 和程序逻辑相关的,可以避免的
- Throwable 的继承关系
按照处理方式不同分类
- checked exception:语法要求必须要用 try catch 或者 throws 语句处理的异常
- unchecked exception:语法不要求一定要用 try catch 或者 throws 语句处理的异常
- Error 和 RuntimeException 是 unchecked exception 的父类。 我们一般使用 RuntimeException
必须要处理的异常:
public class MustHandel {
public static void main(String[] args) throws ClassNotFoundException {
try {
Class clazz = Class.forName("com.geekbang.exception.MustHandle");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
不一定要处理的异常
public class NotHaveToHandle {
public static void main(String[] args) throws NullPointerException{
String str = null;
str.toLowerCase();
}
}
throws 抛出异常
public class ThrowIt {
// >> TODO 可以使用throws关键字,抛出一个异常。
// >> TODO 抛出的异常类型,可以是实际异常的父类或者本身。
// >> TODO 可以抛出多种类型的异常,用逗号分开就可以。
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class clazz = Class.forName("abc");
clazz.getField("");
}
创建异常
public class NewAndThrowIt {
public static void main(String[] args) throws Exception {
causeException();
}
public static void causeException() throws Exception {
// >> TODO 可以创建一个checked exception,然后用throw关键字扔出去
// >> TODO 这时候就需要方法也要有throws语句,同样的,throws语句的类型要能覆盖实际异常的类型
throw new Exception("");
}
public static void causeRuntimeException() throws RuntimeException {
// >> TODO 可以创建一个unchecked exception,然后用throw关键字扔出去
// >> TODO 这时候,方法可以有,也可以没有throws语句
throw new RuntimeException("");
}
}
子类可以继承父类的异常,父类是 exception , 子类可以抛出 exception 和 RuntimeException。 父类没有抛出异常的,子类不能抛出 exception 异常,只能抛出 RuntimeException
Java 异常的传递
自定义异常
异常最重要的信息:类型, 错误信息和出错时的调用栈
public class MyException extends Exception {
public MyException() {
}
public MyException(String message) {
super(message);
}
public MyException(String message, Throwable cause) {
super(message, cause);
}
public MyException(Throwable cause) {
super(cause);
}
}
public class MyRuntimeException extends RuntimeException {
public MyRuntimeException() {
}
public MyRuntimeException(String message) {
super(message);
}
public MyRuntimeException(String message, Throwable cause) {
super(message, cause);
}
public MyRuntimeException(Throwable cause) {
super(cause);
}
}
包装 exception
public class Caller3 {
// >> TODO 可以将checked exception包装成unchecked exception或者checked exception。反之也可以
public void callThrowRTException() {
// >> TODO 可以在这里catch异常,然后封装成自己的异常,并增加相应的异常描述
System.out.println("Caller3.callThrowRTException开始");
try {
Object n = null;
n.toString();
} catch (Exception ex) {
throw new MyRuntimeException("执行callThrowRTException出错", ex);
}
System.out.println("Caller3.callThrowRTException结束");
}
public void callThrowException() throws MyException {
// >> TODO 可以在这里catch异常,然后封装成自己的异常,并增加相应的异常描述
System.out.println("Caller3.callThrowException开始");
try {
Class.forName("com.neverland.Rabbit");
} catch (ClassNotFoundException ex) {
throw new MyException("", ex);
}
System.out.println("Caller3.callThrowException结束");
}
}
try catch finally
try 没有抛出异常, finally 也需要执行, catch 捕捉了异常,finally 也要执行。即使 try 和 catch 中有 return 语句
public class TryFinallyAppMain {
private static int VAL = 0;
public static void main(String[] args) {
System.out.println(withFinally());
System.out.println(VAL);
}
private static int withFinally() {
int len = 0;
try {
String s = null;
// String s = "abc";
return s.length();
}catch (Exception ex){
len = -1;
return len;
} finally {
// >> TODO 可以认为finally语句会在方法返回后,后面的方法开始前,会在return语句后
// >> TODO 无论是因为return结束还是因为异常结束,finally语句都会执行
System.out.println("执行finally语句");
// >> TODO finally里最好不要有return语句,会打乱exception的传递
// return -2;
// >> TODO finally里给return用的变量值赋值没用
// len = -2;
// VAL = 999;
// System.out.println("finally语句执行完毕");
}
}
try finally
catch 多种异常
try catch catch
try catch (Exception1 | exception2)
自动回收资源的 try 语句
网络、文件等
public class MyAutoClosableResource implements AutoCloseable {
private String resName;
private int counter;
public MyAutoClosableResource(String resName) {
this.resName = resName;
}
public String read() throws IOException {
counter++;
if (Math.random() > 0.1) {
return "You got lucky to read from " + resName + " for " + counter + " times...";
} else {
throw new IOException("resource不存在哦");
}
}
@Override
public void close() throws Exception {
System.out.println("资源释放了:" + resName);
}
}
public class TryWithResource {
public static void main(String[] args) {
try (
MyAutoClosableResource res1 = new MyAutoClosableResource("res1");
MyAutoClosableResource res2 = new MyAutoClosableResource("res2")
) {
while (true) {
System.out.println(res1.read());
System.out.println(res2.read());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Java 中的常见异常
- NullPointerException
- IndexOutOfBoundsException
- ClassCastException
- ClassNotFoundException
- IOException