秦疆的JavaSE课程笔记:78 异常 捕获和抛出异常
-
异常处理五个关键词:
try
,catch
,finally
,throw
,throws
-
写一个会出错的代码:
public class Test1 {
public static void main(String[] args) {
int a = 1;
int b = 0;
System.out.println(a/b);
}
}
====运行报错====
Exception in thread "main" java.lang.ArithmeticException: / by zero
- 加上异常处理机制:
public class Test1 {
public static void main(String[] args) {
int a = 1;
int b = 0;
try { //`try`监控区域
System.out.println(a/b);
} catch(ArithmeticException e) { //`catch`捕获异常
System.out.println("异常:除数不得为0!");
} finally { //`finally`处理善后工作
System.out.println("finally");
}
}
}
====运行结果====
异常:除数不得为0!
finally
finally
语句不是必须的,之后学习I0流、资源等相关内容,需要一些关闭操作,可以写在fianlly
语句中。- 将上面的演示修改一下,用一个循环调用,代替除以0错误。
public class Test2 {
public static void main(String[] args) {
try {
new Test().a();
} catch(ArithmeticException e) { //捕获异常的类型是错误的
System.out.println("出错了!");
} finally {
System.out.println("finally");
}
}
public void a() {b();}
public void b() {a();}
}
====运行结果====
finally //未能捕获异常,但是finally依旧被执行了
Exception in thread "main" java.lang.StackOverflowError //报Error
- 将上述代码中
catch()
语句改为catch(Throwable e)
,之前说过Throwable
是所有异常和错误的基部类,可以捕获所有异常。
public class Test2 {
public static void main(String[] args) {
try {
new Test().a();
} catch(Throwable e) {
System.out.println("出错了!");
} finally {
System.out.println("finally");
}
}
public void a() {b();}
public void b() {a();}
}
====运行结果====
出错了! //成功捕获
finally
try…catch
语句是可以像if…else
语句的格式一样,捕获多个可能的异常,试试从子类到父类的异常捕获:
public class Test3 {
public static void main(String[] args) {
int a = 1;
int b = 0;
try {
System.out.println(a/b);
} catch(ArithmeticException e) {
System.out.println("ArithmeticException");
} catch(Exception e) {
System.out.println("Exception");
} catch(Throwable e) {
System.out.println("Throwable");
} finally {
System.out.println("finally");
}
}
}
====运行结果====
ArithmeticException
finally
-
若需要捕获多个异常,则需要从小到大去捕获。
-
如果将父类异常写在子类异常的前面,那么IDEA里子类异常的语句就会报错:已捕捉到异常。
-
IDEA中,选中需要捕捉异常的代码块(比如上述例子中的
System.out.println(a/b);
),使用快捷键Ctrl
+Alt
+T
,在弹出的“包围方式”菜单中,(通常情况)选择try/catch/finally
,则会自动生成异常捕获语句。(这里生成的语句,JDK21和JDK8不太一样。) -
主动抛出异常:
throw
,throws
,一般用在方法中。
public class Test4 {
public static void main(String[] args) {
new Test4().test(1,0);
}
public void test(int a,int b) {
if (b==0) {
throw new ArithmeticException();
}
System.out.println(a/b);
}
}
- 假设在方法中处理不了这个异常,就在方法上抛出异常。
public class Test5 {
public static void main(String[] args) {
try {
new Test5().test(1,0);
} catch (ArithmeticException e) {
throw new RuntimeException(e);
}
}
public void test(int a,int b) throws ArithmeticException {
if (b==0) {
throw new ArithmeticException();
}
System.out.println(a/b);
}
}
- 按照秦疆老师的说法,这样的处理方法在抛出异常的同时不妨碍程序继续执行,但是没有做具体演示,上述代码可能并不是一个理想案例,我暂时也不知道该怎么演示
throws
的功能。