11.异常类处理

1.JVM的默认处理方案 

        如果程序出现了问题,我们没有做任何处理,最终JVM会做默认的处理

  • 把异常的名称,异常原因及异常出现的位置等信息输出在控制台
  • 程序停止执行

2. 异常处理类的体系结构

       程序出现异常是一个正常现象,就像人会生病一样。

(1)Java类中异常类Throwable[类]顶级异常类

(2)Throwable[类]有两个子类:1.Error(错误) 2.Exception(异常)

(3)Exception又被分为运行时异常与非运行时异常(编译时异常)。

      ①运行时异常--非检查性异常 ,在代码编写使,可以忽略捕获操作(比如:ArrayIndexOutOfBoundsException),这种异常是在代码编写或者使用过程中通过规范可以避免发生的。

      ②非运行时异常--检查性异常,必须在编写代码时,使用try catch捕获(比如:IOException异常)。

 

 

3.Error与Exception的区别

      (1)Error是java程序运行中不可预料的异常情况,这种异常发生以后,会直接导致JVM不可处理或者不可恢复的情况。所以这种异常不可能抓取到,比如OutOfMemoryError、NoClassDefFoundError等。【癌症】

      (2)Exception是java程序运行中可预料的异常情况,咱们可以获取到这种异常,并且对这种异常进行业务外的处理。【感冒】

4. java异常处理的原理

如果程序出现了问题,需要我们自己处理,有两只方式:

  1. try………catch……..
  2. throws

4.1 异常可以自己处理—try…catch… 

      (1)try-catch代码块格式

      try{

         可能出现异常的代码;

         }catch(异常类名  变量名){

                  异常的处理代码;

}

       (2)执行流程:

      程序从try里面的代码开始执行,出现异常,会自动生成一个异常类对象,该异常对象被提交给java运行时系统,当java运行时系统接收到异常对象时,会到catch中去找匹配的异常类,找到后进行异常的处理,执行完毕之后,程序还可以继续往下执行。

通过try-catch代码块处理异常,将可能出现异常的java代码使用try{异常可能发生的代码}catch(要抓捕的异常){异常处理方式}块包裹,如果出现异常try{}就会捕获异常,终止代码的运行,将捕获的异常交给catch(){}去处理异常。

        (3)try{}--捕获可能发生的异常;

       catch(要抓捕的异常){异常处理方式}---抓获处理异常;

catch后面的“()”中一般要定义为具体异常类型的。具体异常类型不明确的时候可以使用Exception/Throwable

catch的{}--- 具体异常的处理过程。往往都是打印堆栈到控制台,查看具体情况,修改程序去避免。-----变量.printStackTrace();

      (4)一个try{}后面可以跟随多个catch(要抓捕的异常){异常处理方式},多个catch时要抓捕的异常类型需要按照有小到大的顺序排列。

      (5)【finally{ }】---出现在catch的“{ }”后面,可以写也可以不写。

           finally{ }表示有无异常都要执行的动作,当有一定需要执行的代码时可以写进finally中。

例:

public class ExceptionDemo1 {

      public static void method(){

            //异常处理

            try{

            int[] arr={1,2,3};

            System.out.println(arr[2]);

            //没报错,但是运行会报错,因为这里数组存储空间最大为2

            System.out.println(arr[3]);

            }catch(Exception e){

                  e.printStackTrace();

            }

            System.out.println("我真棒");//此处继续被执行,如果没有try..catch,此处就没有被执行

      }

}

public class Main {

      public static void main(String[] args) {

            ExceptionDemo1 ec=new ExceptionDemo1();

            ec.method();

           

      }

}

控制台:

3

java.lang.ArrayIndexOutOfBoundsException: 3

我真棒

      at lianxi20211106.ExceptionDemo1.method(ExceptionDemo1.java:10)

      at lianxi20211106.Main.main(Main.java:6)

问题:try catch中return在finally之前还是之后执行?     

 public class TestClass {

      public static String method(){

            String he="你好";

            try{

                  he="hello";

                  return "swr";

            }catch(Exception e){

                  e.printStackTrace();

            }finally{

            System.out.println("无论有没有异常都要执行");

                  he="sds";

            }

            return he;

      }

     

      public static void main(String args[]){

             String val=TestClass.method();

             System.out.println("返回值=="+val);

      }

}

输出:

无论有没有异常都要执行

返回值==swr

结论:finally语句在return语句执行之后return返回之前执行的。

4.2 异常不自己处理---throws

       虽然我们通过try…catch..,可以对异常进行处理,但并不是所有的情况我们都有权限进行异常的处理,有些时候可能出现的异常是我们处理不了的,这个时候咋办呢?针对此情况,java提供了throws处理方案。

      (1)格式:throws  异常类名;

            注意:这个格式是跟在方法的括号后面的

  1. 编译时异常必须要进行处理,可以try…catch…或者throws,如果采用throws方案,将来谁调用谁处理;
  2. 运行时异常可以不处理,出现问题后,需要我们回来修改代码。

     (2)如果出现异常,java会根据问题所描述的异常类,创建一个对象(实例)具体异常对象,然后将该对象抛给上一级【谁调用谁就是上一级】。

      (3)具体步骤:

      method具体出异常处 --》main主方法--》jvm虚拟机--》将异常出现的位置和原因打印在控制台上。

      throws--声明方法抛出异常给上一级【谁调用谁就是上一级】

例:

public class TestClass {

      public int  getInt()throws Exception{

            int a=10;

            int b=0;

            int c=a/b;

            return c;

      }

}

public class Main {

      public static void main(String[] args) throws Exception{

            TestClass tc=new TestClass();

            int  res=tc.getInt();

            System.out.println("res=="+res);

      }

}

控制台:

Exception in thread "main" java.lang.ArithmeticException: / by zero

      at com.wangxing.test2.TestClass.getInt(TestClass.java:8)

      at com.wangxing.test2.Main.main(Main.java:7)

5. 自定义异常和throw

       简单的自定义异常--编写一个新类,继承Throwable/Exception/RumtimeException,在构造中访问父类的构造方法。

      (1)格式:

      public class 异常类名 extends Exception{

                  无参构造

                  有参构造

      }

      (2)范例1:数组大小不能为负值的错误例子

public class MyException extends Exception{

      public MyException(){

            //无参

      }

      public MyException(String message){

      //访问父类有参数时,要super(参数)写出

            super(message);

      }

}





public class MyArray {

      //数组大小不能为负值的错误例子

      private int size=0;

      public MyArray(int size) throws MyException{

            if(size>0){

                  this.size=size;

            }else{

                  //手动引发一个异常

                  throw new MyException("数组大小不能为负值!");

            }

      }

      public int[] createIntArray(){

            int arr[]=new int[this.size];//创建数组

            return arr;

      }

}

测试类:

public class ArrayMain {

      public static void main(String[] args) throws MyException{

                  MyArray ma=new MyArray(-5);

                  int arr[]=ma.createIntArray();

      }

}

      //或者

/*   public static void main(String[] args) throws MyException{

            try{

                  MyArray ma=new MyArray(-5);

                  int arr[]=ma.createIntArray();

            }catch(MyException e){

            e.printStackTrace();

            }

      }

}*/

控制台:

Exception in thread "main" com.weiwei.test3.MyException: 数组大小不能为负值!

      at com.weiwei.test3.MyArray.<init>(MyArray.java:11)

      at com.weiwei.test3.ArrayMain.main(ArrayMain.java:6)

(3)范例2:分数在0—100之间

public class MyException extends Exception{

            public MyException(){



            }

            public MyException(String message){

                  super(message);

            }

     

}



public class Teacher {

      //检查学生分数的例子

      public void checkScore(int score) throws MyException{

            if(score<0||score>100){

                  //当throw出现时,方法括号后就要加throws,不然报错

                  throw new MyException("你给的分数有误,分数应在0-100之间");

            }else{

                  System.out.println("分数正常");

            }

      }

}

测试类1:

import java.util.Scanner;



public class Main {



      public static void main(String[] args) throws MyException{

            System.out.println("请输入分数");

            //创建输入

            Scanner sc=new Scanner(System.in);

            int score=sc.nextInt();

           

            Teacher t=new Teacher();

            t.checkScore(score);

      }



}

测试类2:

import java.util.Scanner;



public class Main2 {



      public static void main(String[] args){

            System.out.println("请输入分数");

            //创建输入

            Scanner sc=new Scanner(System.in);

            int score=sc.nextInt();

           

            Teacher t=new Teacher();

            try{

                  t.checkScore(score);

            }catch(MyException e){

                  e.printStackTrace();

            }

      }

}

总结一下:

(1)如果有异常就try{}catch(){},如果不想try{}catch(){}那么就声明方法throws异常。

(2)没有特殊要求的时候我们都是打印堆栈异常,查看程序的具体异常和位置,方便修改。

(3)我们轻易不会自己定义异常,因为java提供的异常类型已经足够使用。

6. throws和throw的区别

throws

throw

用在方法声明后面,跟的是异常类名

用在方法体内,跟的是异常对象名

表示抛出异常,由该方法的调用这来处理

表示抛出异常,由方法体内的语句处理

表示出现异常的一种可能性,并不一定会发生这些异常

执行throw一定抛出了某种异常

7. java中的常见运行时异常

  1. NullPointerException - 空指针引用异常
  2. ClassCastException - 类型强制转换异常。
  3. IllegalArgumentException - 传递非法参数异常。
  4. ArithmeticException - 算术运算异常
  5. ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
  6. IndexOutOfBoundsException - 下标越界异常
  7. NegativeArraySizeException - 创建一个大小为负数的数组错误异常
  8. NumberFormatException - 数字格式异常
  9. SecurityException - 安全异常
  10. UnsupportedOperationException - 不支持的操作异常

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java-请多指教

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值