Java 异常解析

异常

1、什么是异常

例如除数不能为0,否则报错

2、try…catch 和finally

为了解决异常,java提供对异常进行处理的方式,异常捕获。使用try…catch语句实现

try{
	//程序代码块
}catch (Exception e){   //Exception类或其子类
	//对ExceptionType的处理
}

说明:在try中放可能出现异常的语句,在catch中放针对异常进行处理的代码。

package review;

//1.接口
interface Animal{
    void shout();
}
public class r1 {
    public static void main(String[] args) {
        try{
            int re = divide(4,0);
            System.out.println(re);
        } catch(Exception e){ //参数是Exception类
            System.out.println("捕获的异常信息:"+e.getMessage());
        }
        System.out.println("程序继续向下执行");
    }
    public static int divide(int x , int y){
        int r = x / y;
        return r;
    }
}
捕获的异常信息:/ by zero
程序继续向下执行

发生异常语句后面的代码不会被执行。

如果希望有些语句无论程序是否发生异常都要执行,这时需要在try…catch语句后面加一个finally代码块。

package review;

//1.接口
interface Animal{
    void shout();
}
public class r1 {
    public static void main(String[] args) {
        try{
            int re = divide(4,0);
            System.out.println(re);
        } catch(Exception e){ //参数是Exception类
            System.out.println("捕获的异常信息:"+e.getMessage());
            return;//程序结束,后面除过finally代码块中的语句,其他语句都不会被执行
        } finally {
            System.out.println("finally代码块");//finally代码块无论程序提前结束都会执行
        }
        System.out.println("程序继续向下执行");//程序结束不执行
    }
    public static int divide(int x , int y){
        int r = x / y;
        return r;
    }
}
捕获的异常信息:/ by zero
finally代码块

finally代码块无论程序提前结束都会执行,不受return影响。

但受System.exit(0);因为该语句表示退出java虚拟机,任何代码都运行不了。

3、throws关键字

在方法的后面使用throws关键字对外声明该方法有可能发生的异常,从而检查方法中是否存在异常。

throws关键字声明抛出异常的语法格式:

修饰符 返回类型 方法名(参数表) throws 异常类1 , 异常类2...{
	//方法体
} 
 public static void main(String[] args){
        int re = divide(4 , 2);
        System.out.println(re);
    }
	//使用throws声明抛出异常
    public static int divide(int x , int y) throws Exception {
        int r = x / y;
        return r;
    }
//未报告的异常错误java.lang.Exception; 必须对其进行捕获或声明以便抛出

在前面调用divide方法时,就出现了抛出异常,不能除0的异常,所以程序直接不能编译,报错。

说明divide 方法存在错误。

最终导致程序不能正常运行,计算4/2

若要程序还能够继续运行,方法:

(1)用try…catch处理divide方法抛出的异常

package review;

public class r1 {
    public static void main(String[] args) {
        try{
            int re = divide(4,2);
            System.out.println(re);
        } catch(Exception e){
           e.printStackTrace(); //打印捕获的异常信息
        }
    }
    public static int divide(int x , int y) throws Exception {
        int r = x / y;
        return r;
    }
}
2

(2)若不会try…catch将异常抛出,也可以使用throws关键字继续将异常抛出。

给调用方法的方法中加throws,如在main中加

package review;

public class r1 {
    public static void main(String[] args) throws Exception {
            int re = divide(4,2);
            System.out.println(re);

    }
    public static int divide(int x , int y) throws Exception {
        int r = x / y;
        return r;
    }
}
2

4、编译时异常与运行时异常

在程序编译时产生的异常,必须对这些异常进行处理,这种异常称为编译时异常,也称checked异常。

在运行时产生的,不编写异常处理代码依然可以通过编译,称为运行时异常,也称unchecked异常。

(1)编译时异常

在Exception类中,除RuntimeException类及其子类外,Exception的其他子类都是编译时异常。

出现异常后必须对异常进行处理,否则不会编译。

处理方法为:try…catch对异常进行捕获处理;throws关键字声明抛出异常,调用者对异常进行处理。

(2)运行时异常

RuntimeException类及其子类都是运行时异常。

编译器不会对该类异常进行检查,换句话说,就是当程序中出现这类异常时,即使没有使用try…catch语句捕获或使用throws声明抛出异常,程序也能编译通过。

如,数组越界,就会发生运行异常,仍会编译通过。

int[] arr = new int[5];
System.out.println(arr[6]);

5、自定义异常

java允许用户自定义异常,但自定义的异常类必须继承自Exception或其子类。

自定义异常:

//1.自定义异常继承Exception
class Divide extends Exception{
    public Divide(){
        super(); //调用Exception的构造方法
    }
    public Divide(String message){
        super(message);
    }
}

(1)自定义异常中使用throw关键字在方法中声明异常的实例对象:(而非throws)

throw Exception 异常对象

(2)使用throw关键字在方法中向调用者抛出自定义的Divide异常对象:

package review;

//1.自定义异常继承Exception
class Divide extends Exception{
    public Divide(){
        super(); //调用Exception的构造方法
    }
    public Divide(String message){
        super(message);
    }
}
public class r1 {
    public static void main(String[] args) throws Exception {
            int re = divide(4,-2);//不允许被除数是负数,否则出现异常
            System.out.println(re);

    }
    public static int divide(int x , int y) {
        if(y < 0){
            throw new Divide("除数是负数");//标红,报错,编译不通过
        }
        int r = x / y;
        return r;
    }
}

为什么不会编译通过?

是因为在一个方法内使用throw关键字抛出异常对象时,必须要使用try…catch语句对抛出的异常进行处理,或者在divide()方法上,使用throws关键字声明抛出异常,从而,程序正常编译。

package review;

//1.自定义异常继承Exception
class Divide extends Exception{
    public Divide(){
        super(); //调用Exception的构造方法
    }
    public Divide(String message){
        super(message);
    }
}
public class r1 {
    public static void main(String[] args) throws Exception {
        //2.定义try...catch语句用于捕获异常
        try {
            int re = divide(4, -2);//不允许被除数是负数,否则出现异常
            System.out.println(re);
        } catch (Divide e){    //利用自定义的异常,对捕获到的异常进行处理
            System.out.println(e.getMessage()); //打印捕获到的异常信息
        }
    }
    //3.使用throws关键字声明抛出自定义异常
    public static int divide(int x , int y) throws Divide{
        if(y < 0){
            throw new Divide("除数是负数");
        }
        int r = x / y;
        return r;
    }
}

在调用divide()方法时,传入的除数不能为负数,否则程序会抛出一个自定义的Divide异常,该异常最终被catch代码块捕获处理,并打印异常信息。

程序运行顺序:

调用divide(4, -2) --> throw new Divide()抛出一个异常 --> 跳转到catch处理异常 --> 打印异常信息 --> 程序正常结束。

总之:

(1) 当发生异常时,程序会立即终止,不会向下继续执行,为了就是解决异常,使程序能捕获到异常并打印异常信息,在发生异常后,然后程序不会停止,继续执行,

为了这个目标引进了异常捕获和异常处理,即try…catch语句。

(2)使用throws关键字,来抛出方法中所存在的异常,如果该方法存在异常,则在调用方法时标红报错,

要想解决这个问题,不让报错,想让程序能正常编译运行,有两个方法,一是try…catch捕获异常处理异常(方法调用放在try中),二是在方法调用所在的方法中同样用throws Exception抛出异常。

(3)自定义异常,只是继承Exception派生新的异常类,

使用throw关键字声明异常的实例对象,将该对象放在要发生异常的代码块中,用来判断是否发生异常,

其余异常处理,抛出异常类似于前面,注意在catch声明异常类。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值