美文网首页
Java中的异常与处理

Java中的异常与处理

作者: 向日花开 | 来源:发表于2016-12-22 11:29 被阅读250次

    Java中的异常

    在程序运行时发生了不正常的情况,此时由系统中断程序的运行,包含异常信息、异常类名、异常的位置。

    异常分类
    • Error 错误
      由系统原因造成的,一般是系统资源分配冲突时或系统崩溃等原因,这一类Error错误,对于程序员来说是无法处理的
    • Exception
      由于程序原因造成的,一般是运算、I/O读取等原因,这一类Exception异常,可以进行处理
    Java中异常类的体系

    Throwable、Error、Exception

    在Java中如何处理异常?

    1、捕获异常处理

          try{
           可能出现异常的语句;
          }catch(异常类型 对象名){
           处理异常语句;
           }
    

    2、抛出异常

    • 声明方法时抛出异常

      方法名() throws 异常类名[,异常类名,异常类名] {}
      
    • 在方法中抛出异常

      RuntimeException :非受控异常(运行时异常)  
      

    案例

    public class Demo {
    
        static int divide(int a, int b) throws ArithmeticException {
            int result = 0;
    
            result = a / b; //当发生异常时,向调用者抛出异常
    
            //当异常从某一位置抛出后,其下的语句不会被执行
            System.out.println("计算结果完成....");
    
            return result;
        }
    
    
        public static void main(String[] args) {
            //输入两个数
            Scanner scanner = new Scanner(System.in);
    
            //将数字字符串转成数值类型
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            scanner.close();
            try {
                int r = divide(a, b);
    
                System.out.println(r);
    
            } catch (Exception e) { //可以处理所有异常,即Exception类是所有异常的父类
                e.printStackTrace();
            }
    
    
        }
    }
    

    运行结果

    多个异常处理方式

        try{
    
        }catch(异常类名 对象名){
    
        }catch(...){
    
        }catch(...){
    
        }
    

    注意:处理多个异常类时,异常的子类所在的catch语句要放在最上面。

    案例

    public class Demo {
        static class Person {
            String name;
    
            public Person(String name) {
                this.name = name;
            }
    
            public String toString() {
                return "[name=" + name + "]";
            }
        }
    
        static void sub(int a, int b, int[] nums, Person p) {
            try {
                int r = a / b;//此行如果出现了异常,则下行代码不会执行
                r = nums[5] / 9;
                System.out.println(p);
            } catch (ArithmeticException e) {
                System.out.println("除数为0了...");
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("数组的索引值越界了,数组的长度小于6...");
            } catch (NullPointerException e) {
                System.out.println("访问的对象是null");
            } catch (Exception e) {  //异常类的父类所处于的catch语句要放在最后
                e.printStackTrace();
            }
    
        }
    
        public static void main(String[] args) {
            int[] nums = {9, 10, 8, 66, 22, 109};
    
            sub(10, 2, nums, new Person("张三"));
    
            sub(10, 0, new int[3], null);
    
        }
    }
    

    抛出异常

    • 抛出多个异常

      在方法声明的后边,使用 throws 异常类型列表 语句。

    • 抛出一个异常
      throw new RuntimeException("异常信息")

    案例

    public class Demo {
    
        static class Person {
            String name;
    
            public Person(String name) {
                this.name = name;
            }
    
            public String toString() {
                return "[name=" + name + "]";
            }
        }
    
        //抛出多个异常,抛给调用者处理
        static void sub(int a, int b, int[] nums, Person p)
                throws ArithmeticException, IndexOutOfBoundsException, NullPointerException {
    
            int r = a / b;//此行如果出现了异常,则下行代码不会执行
            r = nums[5] / 9;
            //System.out.println(p.toString());
    
        }
    
        static void div(int a, int b) {
            if (b == 0) {
                //抛出异常
                throw new RuntimeException("除数为0");
            }
        }
    
        public static void main(String[] args) {
            int[] nums = {9, 10, 8, 66, 22, 109};
    
            //sub(10,2,nums,new Person("张三"));
    
            try {
                sub(10, 4, new int[7], null);
    
                div(9, 0);
    
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("数组长度小于6");
            } catch (IndexOutOfBoundsException e) {  //父类的异常处理放在子类异常处理的下方
                System.out.println("索引越界。。。");
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
    }
    

    处理异常的格式(正规的)

    try{
     //资源分配的语句
     }catch(...){
    
    }finally{
    //肯定执行的语句,一般是释放资源的语句,
     //注: 如果try语句中包含return 语句,finally语句在return之前执行
     }
    

    案例

    public class Demo {
    
        static class Student{
            private String name;
            public Student(String name){
                this.name=name;
            }
    
            public int div(int a,int b){
                return a/b;
            }
    
            public String toString(){
                return name;
            }
        }
    
        public static void main(String[] args){
            Student s=new Student("张三");
    
            try{
                s.div(10,0);
    
                return ;
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                System.out.println(s.toString());
    
                s=null;//s所指向的堆内存变是垃圾了,可以被gc回收
    
                System.out.println("回收资源...");
            }
        }
    }
    

    自定义异常

    自定义异常类步骤

    1、创建类,并继承Exception

    2、提供构造方法,可以调用父类的构造方法

    3、使用自定义的类时在方法中,根据条件判断的结果,再通过throw关键向方法的调用者抛出异常

    如:

      void method(int a){
       if(a<0){
      throw new 自定义异常类型("异常信息");
      }
    

    注意:对于抛出的自定义的Exception异常,必须要处理

    案例

    public class Demo {
        static class MyException extends Exception {
            public MyException() {
                super("自定义异常");
            }
    
            public MyException(String msg) {
                super(msg);
            }
        }
    
        static void isZero(int n) throws MyException {
            if (n < 0) {
                //抛出数值不能小于0的异常
                throw new MyException("数值不能小于0!!"); //抛出的一般性异常必须要处理:捕获或抛出
            }
    
            System.out.println("大于0的值--》" + n);
        }
    
        public static void main(String[] args) {
    
            try {
                isZero(-1);
            } catch (MyException e) {
                e.printStackTrace();
            }
    
        }
    }
    

    补充

    Error和Exception有什么区别?

    Error表示系统级的错误和程序不必处理的异常,是恢复不是不可能但很困难的情况下的一种严重问题;比如内存溢出,不可能指望程序能处理这样的情况;Exception表示需要捕捉或者需要程序进行处理的异常,是一种设计或实现问题;也就是说,它表示如果程序运行正常,从不会发生的情况。

    try{}里有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会被执行,什么时候被执行,在return前还是后?

    会执行,在方法返回调用者前执行。

    阐述final、finally、finalize的区别
    • final:修饰符(关键字)有三种用法:如果一个类被声明为final,意味着它不能再派生出新的子类,即不能被继承,因此它和abstract是反义词。将变量声明为final,可以保证它们在使用中不被改变,被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取不可修改。被声明为final的方法也同样只能使用,不能在子类中被重写。
    • finally:通常放在try…catch…的后面构造总是执行代码块,这就意味着程序无论正常执行还是发生异常,这里的代码只要JVM不关闭都能执行,可以将释放外部资源的代码写在finally块中。
    • finalize:Object类中定义的方法,Java中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize()方法可以整理系统资源或者执行其他清理工作。
    说出下面运行结果:类ExampleA继承Exception,类ExampleB继承ExampleA。
      try {
        throw new ExampleB("b")
      } catch(ExampleA e){
        System.out.println("ExampleA");
      } catch(Exception e){
        System.out.println("Exception");
      }
    

    输出:ExampleA。

    常见的运行时异常?
    • NullPointerException (空指针异常)
    • IndexOutOfBoundsException (下标越界异常)
    • ClassCastException (类转换异常)
    • IllegalArgumentException (非法参数异常)
    • ArithmeticException(算术异常)

    相关文章

      网友评论

          本文标题:Java中的异常与处理

          本文链接:https://www.haomeiwen.com/subject/plicvttx.html