异常机制(Exception)

异常机制(Exception)

异常的定义:指程序运行中出现的不期而至的各种状况

  • java中所有错误的超类为:Throwable。其下有两个子类:Error和Exception

  • Error的子类描述的都是系统错误,比如虚拟机内存溢出等。

  • Exception的子类描述的都是程序错误,比如空指针,下表越界等。

  • 通常我们程序中处理的异常都是Exception。

异常处理机制中的try-catch

异常处理机制中的try-catch

  • 语法:

    try{代码片段…}catch(XXXException e){出现错误后的补救措施(B计划)}

  • try{}语句块不能单独写,后面要么跟catch语句块要么跟finally语句块,异常处理机制关注的是:明知道程序可能出现某种错误,但是该错误无法通过修改逻辑完全规避掉时,我们会使用异常处理机制,在出现该错误是提供一种补救办法。凡是能通过逻辑避免的错误都属于bug!就应当通过逻辑去避免!

  • 捕获异常的方式

    //这里只是举例异常,实际操作中空指针是需要修复的,属于bug
    System.out.println("程序开始了");
    String line= null;
    System.out.println(line.length());
    System.out.println("程序结束了");
    //创建一个空指针异常,执行后会显示空指针异常NullPointerException,未抛出或执行操作的话会直接结束程序。不会执行最后一句输出语句
    
    //使用trycatch进行操作,程序不会报错,并且会捕获异常并正常执行至最后
    System.out.println("程序开始了");
    try{
       String line= null;
       System.out.println(line.length());
    }catch (NullPointerException e){
       System.out.println("空指针异常");
    }
    System.out.println("程序结束了");
    
    //异常如果没有进行及时捕捉,仍会报错,而catch是可以写多个的,所以可以多次进行异常捕获
    System.out.println("程序开始了");
    try{
      String line= "";
      System.out.println(line.length());
      System.out.println(line.charAt(0));//返回字符串当前位置上的得字符
      }catch (NullPointerException e){
          System.out.println("空指针异常");
      }catch (StringIndexOutOfBoundsException e){//如果没有则会出现异常字符串下标越界
           System.out.println("字符串下标越界异常");
      }
    System.out.println("程序结束了");
    
    //现在的异常机制是可以同是处理多个异常的,如果两个异常可以用给同一个解决办法,可以合并异常
    System.out.println("程序开始了");
    try{
      String line= "";
      System.out.println(line.length());
      System.out.println(line.charAt(0));//返回字符串当前位置上的得字符
      }catch (NullPointerException|StringIndexOutOfBoundsException e){
                System.out.println("空指针异常或字符串下标越界异常");
      }
    System.out.println("程序结束了");
    
    //因为工作中不一定会囊括所有的错误,所以一般可以在最后设置一个总的异常捕捉,用来进行相关操作
    System.out.println("程序开始了");
    try{
      String line= "abc";
      System.out.println(line.length());
      System.out.println(line.charAt(0));//返回字符串当前位置上的得字符
        System.out.println(Integer.parseInt(line));//将字符串转为int值
      }catch (NullPointerException|StringIndexOutOfBoundsException e){
                System.out.println("空指针异常或字符串下标越界异常");
      }catch (Exception e){
                System.out.println("发生未知错误,请联系相关人员");
      }
    System.out.println("程序结束了");
    
    

​ 注意:当try语句块中语句发生错误后,发生错误语句下面的代码将不会执行,同时catch其中一个捕获异常后,后面的捕获异常(finally语句的代码除外)也将不会在继续执行。

异常处理机制中的finally
  • finally块定义在异常处理机制中的最后一块。它可以直接跟在try之后,或者最后一个catch之后。

  • finally可以保证只要程序执行到了try语句块中,无论try语句块中的代码是否出现异常,最终finally都必定执行。

  • finally通常用来做释放资源这类操作,比如IO操作后的关闭流动作就非常适合在finally中进行

    System.out.println("程序开始了");
    try{
      String line= "abc";
      System.out.println(line.length());
      System.out.println(line.charAt(0));//返回字符串当前位置上的得字符
        return;
        System.out.println(Integer.parseInt(line));//将字符串转为int值
      }catch (Exception e){
                System.out.println("发生未知错误,请联系相关人员");
      }finally {
                System.out.println("finally代码执行了");
      }
    System.out.println("程序结束了");
    
IO操作时的异常处理机制应用
//在实际操作中需要充分考虑到各种情况,及时对问题进行处理
FileOutputStream fos = null;
try {
     fos = new FileOutputStream("fos.dat");
     fos.write(1);
} catch (IOException e) {
     e.printStackTrace();
} finally {
     try {
     if(fos!=null) {
     fos.close();
          }
     } catch (IOException e) {
         e.printStackTrace();
      }
}
自动关闭特性
  • JDK7之后,java提供了一个新的特性:自动关闭。旨在IO操作中可以更简洁的使用异常处理机制完成最后的close操作。
  • 语法:try(定义需要在finally中调用close()方法关闭的对象.){IO操作}catch(XXXException e){ …}
  • 这样代码是编译器认可的,而不是虚拟机。编译器在编译代码后会在编译后的class文件中改回成上面案例的代码样子。
FileOutputStream fos = null;
try (
FileOutputStream fos = new FileOu tputStream("fos.dat")
){
     fos.write(1);
} catch (IOException e) {
     e.printStackTrace();
} 
throw关键字

throw用来对外主动抛出一个异常,通常下面两种情况我们主动对外抛出异常:

  • 1:当程序遇到一个满足语法,但是不满足业务要求时,可以抛出一个异常告知调用者。

  • 2:程序执行遇到一个异常,但是该异常不应当在当前代码片段被解决时可以抛出给调用者。

    //throw抛出异常后,后面的代码就不会继续执行
    //新建测试类Person,里面有sage年龄属性和get/set方法
    Person p = new Person();
    p.setSage(200);//赋值年龄200,满足语法,但是不满足业务
    System.out.println("此人的年龄"+p.getSage());
    
throws关键字

注意,永远不应当在main方法上使用throws!!

当一个方法中使用throw抛出一个非RuntimeException的异常时,就要在该方法上使用throws声明这个异常的抛出。此时调用该方法的代码就必须处理这个异常,否则编译不通过。

//在测试类中修改set方法,进行异常机制抛出
		public void setSage(int sage) throws Exception{
        if (sage<0||sage>150){
            throw new Exception("年龄不合法");
        }
        this.sage = sage;
    }

当我们调用一个含有throws声明异常抛出的方法时,编译器要求我们必须处理这个异常,否则编译不通过。 处理手段有两种:

  • 使用try-catch捕获并处理这个异常

  • 在当前方法(本案例就是main方法)上继续使用throws声明该异常的抛出给调用者解决。 具体选取那种取决于异常处理的责任问题。

    //使用trycatch
    		Person p = new Person();
            try {
                p.setSage(200);//赋值年龄200,满足语法,但是不满足业务
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("此人的年龄"+p.getSage());
    
含有throws的方法被子类重写时的规则
public class ThrowsDemo {
    public void dosome()throws IOException, AWTException {}
}

class SubClass extends ThrowsDemo{
//    public void dosome()throws IOException, AWTException {}

    //允许仅抛出部分异常
//    public void dosome()throws IOException {}

    //允许不再抛出任何异常
//    public void dosome(){}

    //允许抛出超类方法抛出异常的子类型异常
//    public void dosome()throws FileNotFoundException {}

    //不允许抛出额外异常
//    public void dosome()throws SQLException {}

    //不允许抛出超类方法抛出异常的超类型异常
//    public void dosome()throws Exception{}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值