Java:异常

JVM 处理方式
1.把异常的名称,错误原因及异常出现的位置等信息输出在了控制台
2.程序停止执行

1.异常体系

2.编译时异常和运行时异常

  • 编译时异常

    • 都是Exception类及其子类
    • 必须显示处理,否则程序就会发生错误,无法通过编译
  • 运行时异常

    • 都是RuntimeException类及其子类
    • 无需显示处理,也可以和编译时异常一样处理

3:throws方式处理异常

  • 定义格式

    public void 方法() throws 异常类名 {
        
    }
    
  • 示例代码

    public class ExceptionDemo {
        public static void main(String[] args) throws ParseException{
            System.out.println("开始");
    //        method();
              method2();
    
            System.out.println("结束");
        }
    
        //编译时异常
        public static void method2() throws ParseException {
            String s = "2048-08-09";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date d = sdf.parse(s);
            System.out.println(d);
        }
    
        //运行时异常
        public static void method() throws ArrayIndexOutOfBoundsException {
            int[] arr = {1, 2, 3};
            System.out.println(arr[3]);
        }
    }
    
    • 这个throws格式是跟在方法的括号后面的
    • 编译时异常必须要进行处理,两种处理方案:try...catch …或者 throws,如果采用 throws 这种方案,在方法上进行显示声明,将来谁调用这个方法谁处理
    • 运行时异常因为在运行时才会发生,所以在方法后面可以不写,运行时出现异常默认交给jvm处理

4:throw抛出异常

throw new 异常();

  • 这个格式是在方法内的,表示当前代码手动抛出一个异常,下面的代码不用再执行了

  • throws和throw的区别

    throws throw
    用在方法声明后面,跟的是异常类名 用在方法体内,跟的是异常对象名
    表示声明异常,调用该方法有可能会出现这样的异常 表示手动抛出异常对象,由方法体内的语句处理
  • 示例代码

    public class ExceptionDemo8 {
        public static void main(String[] args) {
            //int [] arr = {1,2,3,4,5};
            int [] arr = null;
            printArr(arr);//就会 接收到一个异常.
                            //我们还需要自己处理一下异常.
        }
    
        private static void printArr(int[] arr) {
            if(arr == null){
                //调用者知道成功打印了吗?
                //System.out.println("参数不能为null");
                throw new NullPointerException(); //当参数为null的时候
                                                //手动创建了一个异常对象,抛给了调用者,产生了一个异常
            }else{
                for (int i = 0; i < arr.length; i++) {
                    System.out.println(arr[i]);
                }
            }
        }
    
    }
    

5 try-catch方式处理异常

  • 定义格式

    try {
      可能出现异常的代码;
    } catch(异常类名 变量名) {
      异常的处理代码;
    }
    
  • 执行流程

    • 程序从 try 里面的代码开始执行
    • 出现异常,就会跳转到对应的 catch 里面去执行
    • 执行完毕之后,程序还可以继续往下执行
  • 示例代码

    public class ExceptionDemo01 {
        public static void main(String[] args) {
            System.out.println("开始");
            method();
            System.out.println("结束");
        }
    
        public static void method() {
            try {
                int[] arr = {1, 2, 3};
                System.out.println(arr[3]);
                System.out.println("这里能够访问到吗");
            } catch (ArrayIndexOutOfBoundsException e) {
                System.out.println("你访问的数组索引不存在,请回去修改为正确的索引");
            }
        }
    }
    
  • 注意

    1. 如果 try 中没有遇到问题,怎么执行?
      会把try中所有的代码全部执行完毕,不会执行catch里面的代码

    2. 如果 try 中遇到了问题,那么 try 下面的代码还会执行吗?
      那么直接跳转到对应的catch语句中,try下面的代码就不会再执行了
      当catch里面的语句全部执行完毕,表示整个体系全部执行完全,继续执行下面的代码

    3. 如果出现的问题没有被捕获,那么程序如何运行?
      那么try...catch就相当于没有写.那么也就是自己没有处理.
      默认交给虚拟机处理.

    4. 同时有可能出现多个异常怎么处理?
      出现多个异常,那么就写多个catch就可以了.
      注意点:如果多个异常之间存在子父类关系.那么父类一定要写在下面

4.8 Throwable成员方法(应用)

  • 常用方法

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

   public static void main(String[] args) {
        System.out.println("开始");
        method();
        System.out.println("结束");
    }

    public static void method() {
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[3]); //new ArrayIndexOutOfBoundsException();
            System.out.println("这里能够访问到吗");
        } catch (ArrayIndexOutOfBoundsException e) { //new ArrayIndexOutOfBoundsException();
            // 返回此 throwable 的详细消息字符串
            System.out.println(e.getMessage());

            // 返回此可抛出的简短描述
            System.out.println(e.toString());

            //把异常的错误信息输出在控制台
            e.printStackTrace();

        }
    }

9:自定义异常

  • 实现步骤

    1. 定义异常类
    2. 写继承关系
    3. 提供空参构造
    4. 提供带参构造
  • 代码实现

    异常类

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

    学生类

    public class Student {
        private String name;
        private int age;
    
        public Student() {
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            if(age >= 18 && age <= 25){
                this.age = age;
            }else{
                //如果Java中提供的异常不能满足我们的需求,我们可以使用自定义的异常
                throw new AgeOutOfBoundsException("年龄超出了范围");
            }
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    

    测试类

    public class ExceptionDemo12 {
        public static void main(String[] args) {
            // 键盘录入学生的姓名和年龄,其中年龄为 18 - 25岁,
            // 超出这个范围是异常数据不能赋值.需要重新录入,一直录到正确为止。
    
            Student s = new Student();
    
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入姓名");
            String name = sc.nextLine();
            s.setName(name);
           while(true){
               System.out.println("请输入年龄");
               String ageStr = sc.nextLine();
               try {
                   int age = Integer.parseInt(ageStr);
                   s.setAge(age);
                   break;
               } catch (NumberFormatException e) {
                   System.out.println("请输入一个整数");
                   continue;
               } catch (AgeOutOfBoundsException e) {
                   System.out.println(e.toString());
                   System.out.println("请输入一个符合范围的年龄");
                   continue;
               }
               /*if(age >= 18 && age <=25){
                   s.setAge(age);
                   break;
               }else{
                   System.out.println("请输入符合要求的年龄");
                   continue;
               }*/
           }
            System.out.println(s);
    
        }
    }
    

10:finally

用来创建在 try 代码块后面执行的代码块。无论是否发生异常,finally 代码块中的代码总会被执行。在 finally 代码块中,可以运行清理类型等收尾善后性质的语句

try{
  // 程序代码
}catch(异常类型1 异常的变量名1){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}finally{
  // 程序代码
}
  • 实例
public class ExcepTest{
  public static void main(String args[]){
    int a[] = new int[2];
    try{
       System.out.println("Access element three :" + a[3]);
    }catch(ArrayIndexOutOfBoundsException e){
       System.out.println("Exception thrown  :" + e);
    }
    finally{
       a[0] = 6;
       System.out.println("First element value: " +a[0]);
       System.out.println("The finally statement is executed");
    }
  }
}
  • 注意
    • catch 不能独立于 try 存在。
    • 在 try/catch 后面添加 finally 块并非强制性要求的。
    • try 代码后不能既没 catch 块也没 finally 块。
    • try, catch, finally 块之间不能添加任何代码。

11:try-with-resources

  • DK7 之后,Java 新增的 try-with-resource 语法糖来打开资源,并且可以在语句执行完毕后确保每个资源都被自动关闭 。

  • JDK7 之前所有被打开的系统资源,比如流、文件或者 Socket 连接等,都需要被开发者手动关闭,否则将会造成资源泄露。

try (resource declaration) {
  // 使用的资源
} catch (ExceptionType e1) {
  // 异常块
}

try 用于声明和实例化资源,catch 用于处理关闭资源时可能引发的所有异常。

public class RunoobTest {

    public static void main(String[] args) {
    String line;
        try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
            while ((line = br.readLine()) != null) {
                System.out.println("Line =>"+line);
            }
        } catch (IOException e) {
            System.out.println("IOException in try block =>" + e.getMessage());
        }
    }
}

我们实例一个 BufferedReader 对象从 test.txt 文件中读取数据。
在 try-with-resources 语句中声明和实例化 BufferedReader 对象,执行完毕后实例资源,不需要考虑 try 语句是正常执行还是抛出异常。
如果发生异常,可以使用 catch 来处理异常。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • 【传智播客.黑马程序员训练营成都中心】 Java异常浅析 前言 异常二字,从字面上来理解就是:不正常。程序中的异常...
    OpenCoder阅读 416评论 1 1
  • 异常 概念 异常是程序运行过程中可能发生的一类事件。 当方法中发生错误时,该方法会创建一个对象——异常对象——并将...
    FoxLayla阅读 377评论 0 0
  • 第一节:异常分类 示例图 ThrowableErrorException虚拟机错误内存溢出线程死锁检查异常非检查异...
    张学周阅读 52评论 0 0
  • 1、什么是异常 异常:不是编译错误;编译错误是运行之前检查出来的; 异常是【程序运行时】出现的不正常现象。 2、异...
    XLMN阅读 147评论 0 0
  • 详解Java异常 异常的定义: 异常指不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。异常是一个事件...
    测试开发Kevin阅读 152评论 0 7