自学内容网 自学内容网

java-----异常

目录

异常:代表程序出现的问题

运行时异常和编译时异常的区别?

异常的作用:

异常的处理方式:

异常中常见的方法:

抛出异常:

自定义异常: 


异常:代表程序出现的问题

Exception:叫做异常,代表程序可能出现的问题。我们通常会用Exception以及他的子类来封装程序出现的问题。

运行时异常:RuntimeException及其子类,编译阶段不会出现异常提醒。运行时出现的异常(如:数组索引越界异常)

编译时异常:编译阶段就会出现异常提醒的。(如:日期解析异常)

运行时异常和编译时异常的区别

编译时异常,除了RuntimeException和他的子类,其他都是编译时异常。

编译阶段需要进行处理,作用在于提醒程序员。

运行时异常:

        RuntimeException本身和所有子类,都是运行时异常

        编译阶段不报错,是程序运行时出现的。

        一般是由于参数传递错误带来的问题。

异常的作用:

作用一:异常是用来查询bug的关键参考信息

public class demo4 {
    public static void main(String[] args) {
        int []arr={1,2,3,4};
        System.out.println(arr[5]);
    }
}

我们把这段代码在控制台进行运行,会发现控制台会报下面的错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
    at ExceptionDemo.demo4.main(demo4.java:6)

会发现出现了数组越界异常,并且at是指出错代码的位置,所以异常第一个作用就是告诉你出现了bug,以及bug的信息是什么?

作用二:异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况

想想你下你作为一个调用者,假如要给名字进行赋值,但是你不知道赋值规则是什么?其实编写者在写规则的时候给名字命名了规则,比如必须包含某种符号等,你进行了调用,但是并没有把赋值结果告诉你,只是在控制台进行了调用,你就会很懵逼。这就需要返回异常的信息。

异常的处理方式:

1.JVM默认的处理方式

      .把异常的名称,异常原因以及异常出现的位置信息输出在控制台

      .程序停止执行,异常下面的代码不会执行

public class demo5 {
    public static void main(String[] args) {
        System.out.println(2/0);
        System.out.println("代码执行了吗");//异常下面的代码并没有执行
    }

下面试控制台运行结果

Exception in thread "main" java.lang.ArithmeticException: / by zero 异常名称
    at ExceptionDemo.demo5.main(demo5.java:5) 异常位置

Process finished with exit code 1
 

2.捕获异常

格式:

try{

        可能出现异常的代码;

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

        异常的处理代码

}

目的:当代码出现异常时,可以让程序继续往下执行,不会停止虚拟机.

例子:

public class demo1 {
    public static void main(String[] args) {
        try {
            System.out.println(2/0);//此处出现了异常,程序就会在这里创建一个ArithmeticException对象->new ArithmeticException()
//拿着这个对象到catch的小括号中进行对比,看该异常是否被捕获,然后执行catch对应的代码.
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println(e);
        }catch (ArithmeticException e){
            System.out.println(e);
        }catch (Exception e){
            System.out.println(e);
        }
        System.out.println("看看我执行了吗");//catch里面的代码执行完毕,会执行try...catch体系下面的代码
    }
}

控制台结果:

try....catch四问?

1.如果try中没有问题,怎么执行?

public class demo1 {
    public static void main(String[] args) {
        int []arr={1,2,3,4,5};

        try {
            System.out.println(arr[0]);
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println(e);
        }catch (ArithmeticException e){
            System.out.println(e);
        }catch (Exception e){
            System.out.println(e);
        }
        System.out.println("看看我执行了吗");
    }
}


控制台输出:
1
看看我执行了吗

可以看到:try没有遇到问题,会把try里面所有代码执行完毕,不会执行catch里面的代码

2.如果try中可能会遇到多个问题,怎么执行?

public class demo1 {
    public static void main(String[] args) {
        int []arr={1,2,3,4,5};

        try {
            System.out.println(arr[6]);
            System.out.println(2/0);
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println("索引越界");
        }catch (ArithmeticException e){
            System.out.println("数学异常");
        }catch (Exception e){
            System.out.println(e);
        }
        System.out.println("看看我执行了吗");
    }
}


控制运行结果:
索引越界
看看我执行了吗

可以看到:

当我们执行System.out.println(arr[6]);这里出现数组越界异常,他会直接进行进行对应的catch捕获,然后执行对应的代码,再执行try..catch块下面的代码。其中有一个小注意点:

当我们要捕获的异常,存在父子关系的时候:要把父亲放在最下面,想一下,如果父亲在下面,不管什么异常都会被父亲所捕获,那么下面的异常永远无法被捕获到。

第三问:try中的问题没有被捕获会怎么样?

public class demo1 {
    public static void main(String[] args) {
        int []arr={1,2,3,4,5};

        try {
            System.out.println(2/0);
        }catch (ArrayIndexOutOfBoundsException e){
            System.out.println("索引越界");
        }catch (NullPointerException e){
            System.out.println("数学异常");
        }
        System.out.println("看看我执行了吗");
    }
}


控制台输出:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ExceptionDemo.demo1.main(demo1.java:8)

Process finished with exit code 1

可以看到,try中没有捕获到对应的异常,那么就会执行虚拟机默认的处理方式

第四问:try中遇到多个问题,下面的代码还会执行吗?

        从上面代码可以看出,try中遇到问题,就不会往下执行,会直接执行catch捕获的代码。但是try...catch块下面的代码还会执行。

异常中常见的方法:

方法名称说明
public  String getMessag()返回此throwable的详细消息字符串
public String toString()返回此可抛出的简短描述
public void printStackTrace()把异常的错误信息输出在控制台

这里只演示比较常用的

public class demo1 {
    public static void main(String[] args) {
        int []arr={1,2,3,4,5};

        try {
            System.out.println(arr[6]);
        }catch (ArrayIndexOutOfBoundsException e){
            e.printStackTrace();
        }catch (NullPointerException e){
            System.out.println("数学异常");
        }
        System.out.println("看看我执行了吗");
    }
}

控制台输出:
看看我执行了吗
java.lang.ArrayIndexOutOfBoundsException: 6
at ExceptionDemo.demo1.main(demo1.java:8)

可以看到这个e.printStackTrace();仅仅把错误的信息输出在控制台,不会停止程序运行

抛出异常:

throws

写在方法定义出,表示声明一个异常 告诉调用这,使用本方法可能会有哪些异常?

编译时异常:必须要写

运行时异常:可以不写
格式:

public void 方法() throws 异常类名1...{

        ....

}

例子:

public class throwDemo1 {
    public static void main(String[] args) {
        int []arr={};
        int max= 0;
        try {
            max = getMax(arr); //getMax抛出异常之后,调用者可以选择处理或者不处理,但是这样的话会导致下面代码不能执行,所以用try...catch的方法
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(max);

    }
    public static int getMax(int []arr){ /*throws NullPointerException 运行时异常我们可以省略不写*/
        if(arr==null){
            //手动创建一个异常对象,并把这个异常交给方法的调用者处理
            //此时方法会结束,下面的代码不会再执行了。
            throw new NullPointerException();
        }
        int max=arr[0];
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]>max){
                max=arr[i];
            }
        }
        return max;
    }
}

throw

下在方法内,结束方法

手动抛出异常对象,交给调用者,方法中下面的代码不在执行

public void 方法(){

        thorw new NullPointerException();

}

//

自定义异常: 

目的:让控制台的错误更加的见名知意

public void setName(String name) {
    int len=name.length();
    if(len<3||len>10){
        throw new NameFormatException("长度应该是3-10");//这里时自定义抛出的异常,满足自定义的需求
    }
    this.name = name;
}

//自定义的异常类
public class NameFormatException extends RuntimeException{
    public NameFormatException() {
    }

    public NameFormatException(String message) {
        super(message);
    }
}

案例:

package ExceptionDemo;

import java.util.Scanner;

public class demo3 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);

        GirlFriend gf=new GirlFriend();
        try {
            System.out.println("输入姓名");
            String name=sc.nextLine();
            gf.setName(name);

            System.out.println("输入年龄");
            int age=sc.nextInt();
            gf.setAge(age);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }catch (AgeOutOfBoundsException e){
            e.printStackTrace();
        }
        System.out.println(gf);

    }
}

控制台输出:
输入姓名
aa
Exception in thread "main" ExceptionDemo.NameFormatException: 长度应该是3-10
at ExceptionDemo.GirlFriend.setName(GirlFriend.java:30)
at ExceptionDemo.demo3.main(demo3.java:13)

Process finished with exit code 1

可以看到,输出异常的时候会打印自定义的信息:长度应该是3-10

        


原文地址:https://blog.csdn.net/qq_44766305/article/details/142411923

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!