zoukankan      html  css  js  c++  java
  • 异常处理(异常与错误、throws与throw、try...catch...finally、自定义异常类)

    1、异常与错误

    (1)异常与错误https://www.cnblogs.com/zhai1997/p/12735853.html

    错误与异常:错误对于程序而言是致命的,运用java的异常处理机制,异常发生后经过处理,程序还是能正常运行的。如:数组越界异常、除数为0异常等。异常类是指Exception类及其子类。

    抛出异常:发生异常会后,生成异常对象,并把对象提交给运行系统的过程。

    异常对象:由程序本身或java虚拟机产生,一个异常产生一个异常对象。

    (2)异常

    Java 通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java 中,每个异常都是一个对象,它是Throwable 类或其子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。

    (3)常见的运行时异常

    ArithmeticException(算术异常)
    ClassCastException (类转换异常)
    IllegalArgumentException (非法参数异常)
    IndexOutOfBoundsException (下表越界异常)
    NullPointerException (空指针异常)
    SecurityException (安全异常)

    2、异常分类

    (1)运行时期的异常:

    编译时期没有问题,运行时产生错误。运行异常一旦发生,异常后面的代码就不能运行,需要修改代码,抛出的是RuntimeException类或者是他的子类。如:空指针异常、下标越界异常、类型强制转换异常。

    (2)非运行时期的异常:

    如:非法访问异常、类没有找到异常等。

    public class ExceptionDemo {
    public static void main(String[] args) {
        int []a={12,3,456,122};
        int num=a[4];
        System.out.println(num);
    }
    }

     该数组的最大下标为3,但是要输出的数组的下表为4,所以抛出了数组越界异常:java.lang.ArrayIndexOutOfBoundsException

    3、throw关键字

    throw用在方法体内,是抛出一个异常对象,是抛出异常的具体实施。

    在异常类ArrayIndexOutOfBoundsException中,有如下构造方法去创建异常对象:

    import java.util.Scanner;
    
    public class ExceptionDemo {
        public static void main(String[] args) {
            System.out.println("请输入数组的下标");
            Scanner sc = new Scanner(System.in);
            int a = sc.nextInt();
            ExceptionDemo.num(a);
        }
    
        public static void num(int i) {
            int[] a = { 12, 3, 456, 122 };
            if (i >= a.length)
                throw new ArrayIndexOutOfBoundsException("越界异常");
            int num = a[i];
            System.out.println(num);
        }
    }

     4、throws关键字

    当该异常并不需要产生异常的方法去处理,或者不知道如何处理,则用throws在方法头部用throws抛出异常,表名该方法没有对异常处理,由该方法的调用者处理。throws只是对异常的声明,告诉调用者方法内部有异常,且没有处理该异常。

    5、try----catch-----finally语句捕获和处理异常

    try catch finally是直接处理异常,处理完成之后程序继续往下执行。try用来指定一块预防所有“异常”的程序;catch 子句紧跟在try块后面,用来指定你想要捕捉的“异常”的类型;throw 语句用来明确地抛出一个“异常”。finally 为确保一段代码不管发生什么“异常”都被执行一段代码。

    格式:

    try {
        //需要被检测的语句。(可能会产生异常的代码)
    }
    catch(异常类 变量) { //异常的处理语句。  (捕获到异常后的处理代码)
    }
    finally {
        //一定会被执行的语句。(无论是否捕获到异常均会执行)
    }

    数组越界异常的处理:

    package pers.abb.trycatch;
    
    import java.util.Scanner;
    
    public class TryCatch {
        public static void main(String[] args) {
            System.out.println("请输入数组的下标");
            Scanner sc = new Scanner(System.in);
            int a = sc.nextInt();
            TryCatch.num(a);
        }
    
        public static void num(int i) {
            int[] a = { 12, 3, 456, 122 };
            try {
    
                int num = a[i];
                System.out.println(num);
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("数组越界异常发生了。");
    
            } finally {
                a = null;// 内存垃圾清理
    
            }
            System.out.println("异常已经被处理了");
        }
    }

    由运行结果可知,异常发生后,经过catch语句的处理,执行finally语句后,后面的System.out.println("异常已经被处理了");语句依旧能够正常运行。

    finally是一定会执行的代码,通常用来关闭资源

    6、自定义异常类

    系统定义的异常都是系统可以预见的异常,但是在实际运用中,需要我们结合实际情况,创建适合自己程序的异常处理类。例如,人的年龄为负数的异常。

    定义Person类:

    package pers.zzz.Exception;
    
    public class Person {
        private String name;
        private int age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) throws AgeException {//抛出异常给调用者,即main函数
            if (age<0)
            throw new AgeException(age);//异常发生,创建异常类对象
            else this.age=age;
        }
    
    }

    定义异常类:

    package pers.zzz.Exception;
    
    public class AgeException extends Exception{
    int age;
    public  AgeException(int age){
        this.age=age;
    }
    public void show(){
        System.out.println("年龄为负数异常");
    }
    }

    测试类:

    package pers.zzz.Exception;
    
    public class Test {
    public static void main(String[] args) {
        Person p=new Person();
        try {
            p.setAge(-11);
        } catch (AgeException e) {
        System.out.println("年龄定义有误");
        e.show();
        }
    
    }
    }

    总结:

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

     public static int test(){
            int num=1;
            try{
                System.out.println("try:"+num);
                return num;
            }catch (Exception e){
    
            }finally {
                System.out.println("进入finally");
                System.out.println("finally:"+(++num));
            }
            return num;
        }
        public static void main(String[] args) {
            System.out.println("main:"+Test.test());
        }

    测试结果:

    try:1
    进入finally
    finally:2
    main:1

    finally中的语句会被执行,执行过程是先执行try中的语句,但是try中的return不会立即返回给调用者的,需要先执行finally,然后返回try中的返回值,因此,finally中的代码是在return中间执行的

    当finally中也有返回值的情况:

    public static int test(){
            int num=1;
            try{
                System.out.println("try:"+num);
                return num;
            }catch (Exception e){
    
            }finally {
                System.out.println("进入finally");
                System.out.println("finally:"+(++num));
                return num;
            }
        }
        public static void main(String[] args) {
            System.out.println("main:"+Test.test());
        }
    try:1
    进入finally
    finally:2
    main:2

    从测试结果可以看出,没有执行try中的return

  • 相关阅读:
    Ajax:创建提示工具
    Ajax:自动刷新
    Ajax:动态加载列表框
    The Elements of C# Style Packaging
    Ajax:读取响应首部
    Ajax:发送请求与处理响应
    XMLHttpRequest对象
    WPF学习:XAML概述
    Ajax:进度条
    Ajax:数据验证
  • 原文地址:https://www.cnblogs.com/zhai1997/p/11362956.html
Copyright © 2011-2022 走看看