首页 > 其他分享 >异常

异常

时间:2023-09-09 11:57:41浏览次数:24  
标签:int System println 异常 public out

title: 异常
index_img: https://tuchuangs.com/imgs/2023/08/10/6e572ca2666c699d.png
tags:
  - Java SE
categories:
  - Java SE
excerpt: 异常处理

异常

异常继承体系

  • Error系统级错误(不是异常)

  • Exception程序可能出现的问题(不是错误),是异常的父类

  • RuntimeException异常的子类,运行时才会出现

  • 其它异常:异常的子类,编译时异常

    • 必须在编译时期处理

异常的作用

  • 查询bug的关键参考信息
  • 异常可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况【相比直接打印结果,可以知道出错在哪一行,出现了说明问题】

异常处理

JVM默认异常处理

  • 异常的名称、位置、原因等信息输出到控制台。
  • 停止程序(后续代码不再执行)
public class Main {
    public static void main(String[] args) {
        System.out.println("我是测试语句1");
        System.out.println(1 / 0);
        System.out.println("看不见我");
    }
}

image-20230809213416448

try…catch捕获异常

这种方式,当出现异常,程序可以继续执行

用在调用处

格式

jdk7+支持catch中写多个异常(用|),如果多种异常处理相同,可以使用

try{
  可能出现的异常【注意可能】;
}catch(异常类型 变量名){
  异常处理代码;
}

执行流程

  • 没有异常,不会执行catch的语句
public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 3, 5, 7, 9};

        //没有异常
        try {
            System.out.println("正常执行");
        } catch (AbstractMethodError e) {
            System.out.println("数组越界"); //不会执行
        }
        System.out.println("看得见我吗3?");
    }
}

image-20230809221924001

  • 出现异常,该处产生一个相关异常对象【如数组越界】
  • catch中的异常类型变量如果可以接收上方产生的异常(范围大于等于)
    • 可以被接收,然后执行catch中的代码
    • catch中代码执行结束,直接执行try…catch外的代码【不会返回try了】
  • 一次只能产生一个异常,匹配一个catch
public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 3, 5, 7, 9};
        //产生ArrayIndexOutOfBoundsException异常且可以捕获
        try {
            System.out.println("我正常执行");
            System.out.println(arr[10]);
            System.out.println("看不见我"); //不会执行
        } catch (Exception e) {
            System.out.println("数组越界"); 
        }
        System.out.println("看得见我吗?");
    }
}

image-20230809215929328

如果可能产生多个异常,可以写多个catch,但父类异常类型应该写在最后

public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 3, 5, 7, 9};

        try {
            System.out.println("我正常执行");
            System.out.println(arr[10]);
            System.out.println(1 / 0);
            System.out.println(Integer.parseInt("java"));
        } catch (NumberFormatException e) {
            e.printStackTrace();
            System.out.println("字符串格式不符合");
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
            System.out.println("数组越界异常");
        } catch (ArithmeticException e) {
            e.printStackTrace();
            System.out.println("算数异常");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("运行时异常");
        }
        System.out.println("看得见我吗?");
    }
}

image-20230809234144297

  • catch捕获不到异常,不会执行其中的代码
    • 异常不存在,正常执行
    • 异常范围不符,产生了但捕获不到,会交由JVM处理【控制台+终止】
public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 3, 5, 7, 9};
        //产生ArrayIndexOutOfBoundsException异常,但不可捕获
        try {
            System.out.println("正常执行");
            System.out.println(arr[10]);
        } catch (AbstractMethodError e) { //不匹配的异常,jvm处理
            System.out.println("数组越界");
        }
        System.out.println("看得见我吗3?"); ///不会执行
    }
}

image-20230809221654603

Throable提供的方法

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

选其一即可:一般选择printStackTrace(),包含的信息最多。

public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 3, 5, 7, 9};

        //可捕获数组越界异常
        try {
            System.out.println(arr[10]);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("throwable的详细消息字符串:" + e.getMessage());
            System.out.println("异常简短信息:" + e.toString());
            e.printStackTrace(); //将异常错误信息打印在控制台
        }
        System.out.println("看得见我吗3?");
    }
}

image-20230809223131340

抛出异常

throws

  • 用在方法定义处,声明一个异常,本方法可能产生的异常
  • 编译异常必须要写,运行时异常可以不写
public void 方法() throws 异常类型1,异常类型2....{
  ...
}

throw

  • 用在方法内,结束方法
  • 手动抛出异常对象,交给调用者,后面的代码不再执行【虚拟机接管了异常】
public void 方法(){
  throw new NullpointerException();
}

案例

public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 3, 5, 7, 9};
        int[] arr1 = null;
        int[] arr2 = {};
        getMax(arr);
        System.out.println("----------");
        getMax(arr1);
        System.out.println("----------"); //不会执行,上一步throw产生了异常,下面的都不会执行了
        getMax(arr2);
    }

    // NullPointerException,ArrayIndexOutOfBoundsException是运行时异常,对于throws我们可以不用写
    public static int getMax(int[] arr) /*throws NullPointerException,ArrayIndexOutOfBoundsException*/ {
        if (arr == null) {
            throw new NullPointerException("传入数组是null"); //空指针异常
        }
        if (arr.length == 0) {
            throw new ArrayIndexOutOfBoundsException("传入数组长度为0"); //数组越界异常
        }
        System.out.println("如果异常有效我就看不见了");

        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (max < arr[i]) {
                max = arr[i];
            }
        }
        return max;
    }
}

image-20230809230621864

抛出+捕获处理

在上一个案例,我们抛出异常,交由JVM默认处理异常【停止虚拟机执行后续代码】,接下来我们要try…catch自行捕获处理,让后续代码可以执行。

public class Main {
    public static void main(String[] args) {
        int[] arr = {1, 3, 5, 7, 9};
        int[] arr1 = null;
        int[] arr2 = {};

        System.out.println(handleException(arr));  // 输出9
        System.out.println(handleException(arr1)); // 输出"传入数组是null",返回-1
        System.out.println(handleException(arr2)); // 输出"传入数组长度为0",返回-1
    }

    public static int handleException(int[] arr) { //提取异常处理方法
        try {
            return getMax(arr);
        } catch (NullPointerException | ArrayIndexOutOfBoundsException e) {
            System.out.println(e.toString()); // 打印出异常的名字和详细信息
            return -1; // 返回一个默认值
        }
    }

    public static int getMax(int[] arr) {
        if (arr == null) {
            throw new NullPointerException("传入数组是null"); //包含具体的错误信息
        }
        if (arr.length == 0) {
            throw new ArrayIndexOutOfBoundsException("传入数组长度为0"); //包含具体的错误信息
        }
        int max = arr[0];
        for (int j : arr) {
            if (max < j) {
                max = j;
            }
        }
        return max;
    }
}

image-20230809231321304

自定义异常

问题

java提供的异常不满足我们的需求,怎么办?

public class Friend {
    String name;
    int age;

    public Friend() {
    }

    public Friend(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { 
        return name;
    }

    public void setName(String name) { //这里产生的异常在java中没有描述,只好用运行时异常,方法内用throw
      if(name.length()>5){
            throw new RuntimeException();
        }
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) { //这里产生的异常在java中没有描述,只好用运行时异常,throws可以不用(运行时异常可省略)
        if(age<18 || age>40){
            throw new RuntimeException();
        }
        this.age = age;
    }

    public String toString() {
        return "Friend{name = " + name + ", age = " + age + "}";
    }
}
public class Main {
    public static void main(String[] args) {
        Friend friend = new Friend();
        Scanner sc = new Scanner(System.in);

        while (true) { //使用循环产生异常,重写输入
            try {                                            //try...catch捕获异常
                System.out.println("输入你想要的名字:");
                String name = sc.nextLine();
                friend.setName(name); //可能异常

                System.out.println("输入你期望的年龄:");
                String s = sc.nextLine();
                int age = Integer.parseInt(s); //可能异常
                friend.setAge(age); //可能数字格式化异常

                break; //输入正确,跳出循环

            } catch (NumberFormatException e) {   //多张可能异常,可以多写几个catch,父类异常类型在最后
                System.out.println("年龄格式错误");
            } catch (RuntimeException e) {
                System.out.println("姓名或年龄范围错误");
            }
        }
    }
}

image-20230810000351165

书写自定义异常

  • 定义异常类
  • 写继承关系
    • 运行时异常继承RunTimeException【对于上方问日可以继承运行时异常】
    • 编译时异常继承Exception
  • 写空参构造
  • 带参构造
public class NameException extends RuntimeException {
    public NameException() {
    }

    public NameException(String message) {
        super(message);
    }
}
public class AgeException extends RuntimeException {
    public AgeException() {
    }

    public AgeException(String message) {
        super(message);
    }
}
public class Friend {
    String name;
    int age;

    public Friend() {
    }

    public Friend(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name.length() > 5) {
            throw new NameException("ameException:姓名太长"); //注意
        }
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age < 18 || age > 40) {
            throw new AgeException("AgeException:年龄不在范围"); //注意
        }
        this.age = age;
    }

    public String toString() {
        return "Friend{name = " + name + ", age = " + age + "}";
    }
}
public class Main {
    public static void main(String[] args) {
        Friend friend = new Friend();
        Scanner sc = new Scanner(System.in);

        while (true) { //使用循环产生异常,重写输入
            try {
                System.out.println("输入你想要的名字:");
                String name = sc.nextLine();
                friend.setName(name); //可能异常

                System.out.println("输入你期望的年龄:");
                String s = sc.nextLine();
                int age = Integer.parseInt(s); //可能异常
                friend.setAge(age); //可能数字格式化异常

                break; //输入正确,跳出循环

            } catch (NumberFormatException e) {
                System.out.println("年龄格式错误");
            } catch (AgeException e) {  //年龄异常
                e.printStackTrace();
            } catch (NameException e) { //名字异常
                e.printStackTrace();
            }
        }
    }
}

image-20230810000026113

标签:int,System,println,异常,public,out
From: https://www.cnblogs.com/SimpleWord/p/17689196.html

相关文章

  • ConcurrentModificationException异常原因和解决方法
    ConcurrentModificationException异常原因和解决方法publicstaticvoidmain(String[]args){List<Integer>list=newArrayList<Integer>(){{add(1);add(2);add(3);}};Iterator<Intege......
  • live555流媒体服务器在解决客户端异常掉线后没有释放相应资源问题的解决方法
    我们在基于live555研发流媒体服务器EasyRTSPServer,经过一年多的商用,已经表现得非常稳定了,今天有个客户反馈,在客户端突然断电后,EasyRTSPServer中有部分资源没有释放。分析问题压力测试都已经做过了,包括7x24小时不间断的频繁断连,都没有问题。突然断电….这个嘛…还没试过。其实这......
  • live555流媒体服务器解决客户端异常掉线后导致服务端通道阻塞的问题
    live555在Linux环境下会因为客户端异常掉线后,偶现导致部分通道不能再被访问的问题,我们描述一下这个问题修复的过程。本来是分析服务端CLOSE_WAIT的问题,在调试的过程中,却又发现了阻塞,认真分析了live555的事件调用流程后,发现只要从客户端收到数据,就会执行GenericMediaServer::Clien......
  • Python中的异常处理机制
    finally语句是Python中异常处理机制的一部分,它总是会被执行,无论是否发生异常。finally语句通常用于释放资源或执行清理操作。下面是一个简单的例子:try:#代码段1passexceptExceptionType:#代码段2passelse:#代码段3passfinally:#代码段4......
  • 3. Oracle数据库异常关闭,导致错误3. Oracle数据库异常关闭,导致错误ERROR: ORA-01034:
    之前由于电脑没电,强制关机,导致Oracle数据库异常关闭,再次启动电脑登陆数据库时,发生以下错误:当我尝试重新启动数据库时,发生错误:经过查阅资料后得知:缺少INITXE.ORA文件,需要从下图目录中复制到上图指定目录中,并重命名为initXE.ora即可(这里initxxx.ora中的xxx要取决于你的SID)再......
  • 异常处理
    异常处理异常:报错语法异常(错误都是SyntaxError)出现SyntaxError:invalidsyntax语法无效if #SyntaxError0=1 #SyntaxError逻辑异常(错误类型)出现ZeroDivisionError:divisionbyzero除零错误等1/0 #ZeroDivisionErrordic={}print(dic['skldfj']) #......
  • RTSP流媒体服务器EasyNVR视频平台以服务方式启动异常却无报错,该如何解决?
    EasyNVR是基于RTSP/Onvif协议的安防视频云服务平台,可实现设备接入、实时直播、录像、检索与回放、云存储、视频分发、级联等视频能力服务,可覆盖全终端平台(电脑、手机、平板等终端),在智慧工厂、智慧工地、智慧社区、智慧校园等场景中有大量落地应用。 有用户反馈,在项目现场启动Ea......
  • 有意思的bug:Input在谷歌浏览器下会出现异常显示问题!
    ❝这篇文章要感谢抖音:程序员小山与BUG!你说是bug吧也算是bug,不是bug吧也不是bug,不影响使用,触发情况也不多,但万一测试提了这个bug还是要解决的[doge],在此记录一下这个有意思的bug!❞Bug说明谷歌浏览器是前置条件还要加上input输入框但输入框要有2个附加条件:type是number以及css的te......
  • drf—过滤、分页、异常
    session回顾写一个登录接口——保存用户登录状态签发阶段:做了三件事情:1、生成一个随机字符串2、django—session表中插入数据3、把随机字符串以cookie形式返回给前端(存在浏览器的cookie中)认证阶段:前端自动携带cookie到后端,sessionid:随机字符串session的流......
  • drf-排序、过滤、分页、异常处理
    一、排序只有5个接口中的查询所有,才涉及到排序,所以继承GenericViewSet, 使用步骤:1.必须写在继承:GenericAPIView类的视图中才行2.配置类属性:filter_backends=[OrderingFilter]ordering_fields=['id','user_type']#可以排序的字段3.使用:......