解析java异常(二)之处理异常的两种方式
1 自己处理异常
1.1 前提
一次仅能处理一个异常,在try代码块里面遇到异常后,在try代码块中后面的语句都不会执行了
catch匹配顺序是从上往下依次进行匹配的,有就匹配成功,后面catch语句都不执行,否则再往下匹配,总会找到匹配到的,因为我们有一个保底的父类Exception
示例代码
package Work;
public class Test {
public static void main(String[] args){
System.out.println("运行异常前面");
int a= 0;
try {
a = 10/0;
String str=null;
str.toString();
str.toString();
}catch (ArithmeticException e){
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
System.out.println("运行异常后面");
}
}
示例代码运行截图
1.2 语法
try{
}catch(异常类1 e){
//异常处理语句
}catch(异常类2 e){
//异常处理语句
}catch(异常类3 e){
//异常处理语句
}finally{
//异常处理语句
}
1.3 特点
a 可能出现异常的代码(仅限一行)放在try代码块中
b. try…catch…finally的执行顺序(有异常也不会中断程序)
b.1 先执行try,如果有异常,执行对应的异常类型的catch代码块,最后执行finally
示例代码
package Work;
public class Test {
public static void main(String[] args){
System.out.println("运行异常前面");
int a= 0;
try {
a = 15/0;
//出现异常位置后面的代码都不会执行
System.out.println("出现异常后面的位置");
String str=null;
str.toString();
str.toString();
}catch (ArithmeticException e){
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("finally里面的语句");
}
System.out.println("运行异常后面");
}
}
示例代码运行截图
b.2 先执行try,如果没有异常,catch都会忽略;最后执行finally
示例代码
//try里面的所有语句都会执行
package Work;
public class Test {
public static void main(String[] args){
System.out.println("运行异常前面");
int a= 0;
try {
a = 15/4;
//try里面没有异常时,try代码块里面的所有语句都会执行,catch代码块一个都不会执行
System.out.println("try代码块都会执行的");
}catch (ArithmeticException e){
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}finally {
System.out.println("finally里面的语句");
}
System.out.println("运行异常后面");
}
}
示例代码运行截图
1.4 使用的技巧
1.4.1 快捷键生成
Ctrl+Alt+T
1.4.2 思路
a catch里面从小往大写异常类
b. 对每个不同的异常进行不同的逻辑处理
c 然后finally里面写上关闭一些资源
原因:如果用exception接收所有可能的异常的话,那就需要在那个catch代码块里面写if条件判断,明显没有分别在catch里面写代码块结构更加清晰。
2 上抛异常,交给调用处处理
2.1 核心
可以理解成甩锅,本质上自己没有处理,是交给调用者处理,调用者没有处理的话,若抛出的是编译时错误,则编译通不过;若抛出的是运行时错误;则不会要求你去处理错误的(只有运行时出现了这个错误才会让你去处理的)。如果异常传到main方法里面,main方法还继续上抛给JVM虚拟机的话,那么jvm会打印报错信息,程序中断。
2.2 语法
访问权限修饰符 返回值类型 方法名(形参列表) throws 异常类{
//交给方法调用处处理
}
2.3 示例代码
package Work;
public class Test {
public static void main(String[] args) throws Exception{
System.out.println("运行异常前面");
int a= 0;
a = 15/0;
//上抛给虚拟机,虚拟机是不会惯着你的,它是不会帮你处理的
System.out.println("运行异常后面");
}
}
2.4 示例代码运行截图
2.5 注意点
如果方法处上抛了编译时异常,那么在方法调用处的时候一定要处理异常,不然程序编译都通不过,上抛的是运行时异常,编译不报错,但运行的时候有可能会报错
抛出的异常是编译异常时
示例代码
package Work;
import java.io.FileNotFoundException;
public class Test {
public static void main(String[] args){
fn();
}
public static void fn() throws FileNotFoundException{
int a=10,b=0;
int c=a/b;
System.out.println("异常后面的语句");
}
}
//FileNotFoundException是编译时异常,因此编译时必须要处理
示例代码截图
抛出的异常是运行时异常时
示例代码
package Work;
import java.io.FileNotFoundException;
public class Test {
public static void main(String[] args){
System.out.println("前面的语句");
fn();
System.out.println("测试抛出运行时异常时,后面的语句是否会中断");
}
public static void fn() throws ArithmeticException{
int a=10,b=0;
int c=a/b;
System.out.println("异常后面的语句");
}
}
示例代码截图
3.finally什么时候执行,什么时候不会执行
3.1 当在try里面遇到return方法时,会执行完finally之后再退出,其返回值在try里面中返回的那个值,不会随着finally值的改变而改变
示例代码
package Work;
public class Test {
public static void main(String[] args){
System.out.println("调用函数的结果为: "+fn());
}
public static int fn(){
int i=1;
try {
//即使try..catch里面有return语句;finally语句还是会执行,它是会在执行完fianlly再去返回值,
// 返回值是最初try或catch里面拿到的那个值
return i;
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("进入了");
++i;
}
return 4;
}
}
示例代码运行截图
3.2 当在try里面遇到System.exit(0)时,此时代表虚拟机退出,finally不执行,整个程序都会退出的
示例代码
package Work;
public class Test {
public static void main(String[] args){
System.out.println("调用函数的结果为: "+fn());
System.out.println("测试能否运行");
}
public static int fn(){
int i=1;
try {
//只要遇到System.exit(0),直接退出虚拟机了,整个程序都不会运行了
System.exit(0);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("进入了");
++i;
}
return 4;
}
}
示例代码运行截图
3.3 除了以上的两种情况外,其他时候Finally一直都会执行的
示例代码
package Work;
public class Test {
public static void main(String[] args){
System.out.println("调用函数的结果为: "+fn());
}
public static int fn(){
int i=1;
try {
i=i/0;
//就相当于操作是无效操作,i还是会是原来的那个i
} catch (Exception e) {
System.out.println("异常信息: "+e.getMessage());
} finally {
System.out.println("进入了");
++i;
}
return i;
}
}