JAVA 异常处理

异常处理

异常概述

Throwable是错误和异常的父类,Throwable分为Error和Exception。
Error属于严重性问题,程序员解决不了的错误,像内存溢出等都属于Error。
Exception是异常 我们可以通过写程序来处理它。异常又分为编译期异常和运行期异常。编译期异常是必检异常,我们必须做出异常处理,因为如果发生异常,程序将无法运行。运行期异常属于免检异常,可以对异常作出处理,也可以不做出处理。 但如果我们不做出处理,那么异常最终会交由虚拟机来处理。

运行期异常

运行下面代码就会发生一个异常,因为除数不能是0。当除数是0时,会产生一个ArithmeticException 异常。

int a=1;
int b=0;
System.out.println(a/b);

处理异常

可以使用try-catch-fianlly语句来处理异常。
将可能发生异常的语句放在try语句块中,使用catch语句块来捕获try语句块中可能发生的异常。最终不算异常是否发生,finally语句块中的代码都会执行。
注意
如果catch语句中有return语句,则会先执行finally语句在执行catch中的return语句。而如果catch语句中含有exit则会直接退出虚拟机。

public class ExceptionDemo1{
   public static void main(String[] args) {
       int a=1;
       int b=0;
       //自己尝试捕获处理异常,不再交由虚拟机去处理
       try {
           //try 里面一般放一些可能会出现问题的代码
           System.out.println(a / 0);
           //catche()括号里面放的是 你要捕获的异常类型
       }catch (ArithmeticException e){
           //try里面的代码一旦出现异常,就会执行catch里面的代码
           System.out.println("除数为0了");
       }finally {
           //一般我们会在finally里面做一些善后首尾工作 比如释放一些资源
           System.out.println("finally里面的代码最终都会执行");
           }
       }
   }
}

如果try语句中可能发生多个异常,可以使用多个catch来捕获异常。 但是父类异常的捕获必须放在子类异常的后边,因为异常会被父类捕获,子类就无法捕获。如果是两个平级异常可以使用“|”符号将两个异常放在同一个catch语句中捕获。

public class ExceptionDemo{
   public static void main(String[] args) {
       int a = 1;
       int b = 0;
       int[] arr = {1, 2, 3};
       arr = null;
       //try 里尽量放的是有可能出现问题的代码
       try {
           System.out.println(a / b);
           System.out.println(arr[0]);
           //多个异常:如果是平级关系的异常,谁前谁后无所谓
           //如果多个异常有父子关系,那么父级别的异常放在最后面
           //能明确的异常,尽量明确
       } catch (ArithmeticException e) {
           //catch里面不要做空处理,哪怕你简单的输出一条语句
           b = 1;
           System.out.println("数学异常");
       } catch (NullPointerException e) {
           System.out.println("空指针异常");
       } catch (Exception e) {
           System.out.println("其他异常");
       }
   }
}

编译期异常

编译期异常是指发生在编译期间的异常,该异常必须处理,否则程序无法运行。

public class DateUtils {
    public static Date paseDateStr(String str, String format) throws ParseException{
        SimpleDateFormat format1 = new SimpleDateFormat(format);
        Date parse=null;
             parse = format1.parse(str);
        return parse;
    }
}
public class ExceptionDemo3 {
    public static void main(String[] args){
        //编译期异常:发生在编译期间,必须处理,否则程序无法运行
        String str="2019-10-10";
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
        //可能会发生编译期异常抛出ParseException
            format.parse(str);
        }catch (ParseException e){
            System.out.println("解析失败");
        }
        System.out.println("=======");
    }
}

异常处理的几个方法

getMessage():获取异常信息,返回字符串。
toString():获取异常类名和异常信息,返回字符串。
printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。

public class MyTest {
    public static void main(String[] args) {
        try {
            DateUtils.paseDateStr("2018-10-10","yyyy:MM-dd");
        } catch (ParseException e) {
            System.out.println("------解析异常-----");
            e.printStackTrace();//打印堆栈信息 JVM 默认的处理的方式也是打印异常的堆栈信息
            //String message = e.getMessage();
            //System.out.println(message);
            //System.out.println(e.toString());
        }
        System.out.println("===============================");
    }
}

throws与throw的区别

throws
用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常
throw
用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
这个异常对象可以是编译期异常对象, 可以是运行期异常对象
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定抛出了某种异常

public class ThrowDemo {
    public static void main(String[] args) throws ArithmeticException,NullPointerException,Exception{
 
        yunsuan(1,0);
        System.out.println("abcc");
    }

    private static void yunsuan(int a, int b) {
        if(b!=0){
            System.out.println(a / b);
        }else if(b==0){
            //throw 用在方法内部抛出异常
            throw new ArithmeticException("除数为0");
        }
    }
}

自定义异常类

编写程序,有余额10,若取出存款额大于余额,则抛出自定义的异常。

//自定义异常类public class MyExcepiton extends RuntimeException{
    String name;
    public MyExcepiton(String name) {
       this.name=name;
    }//自定义 异常

    @Override
    public String toString() {
        return  name;
    }
}
public class MyDemo {
    public static void main(String[] args) {
        int money = 100;
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入取款金额");
        int num = scanner.nextInt();
        try{
            if(num<=money){
                money= money-num;
                System.out.println("取款成功");
            }else{
            //抛出异常
                throw new MyExcepiton("余额不足");
            }
        }catch (MyExcepiton e){
            System.err.println(e);
        }
    }
}

注意
父类的方法没有抛出过异常,子类在重写父类方法时,也不能抛出异常,如果重写方法时有异常 你就try 掉
父类和子类都有抛出异常,子类抛出的异常不能比父类大,要么比父类小,或者跟父类一样,或者子类不抛出也可以

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值