Java中的异常与处理

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

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,567评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 对象的创建与销毁 Item 1: 使用static工厂方法,而不是构造函数创建对象:仅仅是创建对象的方法,并非Fa...
    孙小磊阅读 1,957评论 0 3
  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 1,209评论 0 2
  • 咱们华夏民族的“新年”即将来临,家家户户都对新的一年寄寓这很多希望,就比如说像别人的新年小目标“先挣它一个...
    辛小毛阅读 506评论 0 0