Java基础之异常

异常

  • 编译时检测:Exception和其子类(除了RuntimeExpection)
  • 运行时检测:RuntimeException

编译时异常

继承自Exception的,编译时就检查,一般来自外界因素,或者语法错误,比如有时候读文件,当路径错误或者文件名打错了,就会抛出。这种类型的异常抛出后必须处理,比如在某个方法内可能出现该类型的异常,要么在方法头加上throws继续往上抛,直到某一级catch到为止。要么在方法体里try catch,这里处理过了调用时就不用再处理了。当调用该方法时,也可以用throws或者用try catch。

public class Test {
  // 方法体内try-catch
public void run1() {
  try {
            throw new Exception();
        } catch (Exception e) {
            e.printStackTrace();
        }
}

// 方法头throws给上级调用者
public void run2() throws Exception {
        throw new Exception();
}
  
  public static void main(String args[]) /*run2()或者在这里throws*/{
    Test t = new Test();
    t.run1();  // run1()方法体内已经处理,这里不用catch,也不用在main上throws
    
        // run2()只是throws,仅提示这里可能会抛出,并没有处理,所以这里必须处理,要么继续抛(main函数上throws,要么catch)
    try {
        t.run2();
    } catch (Exception e) {
      // 实际开发肯定不能这样,必须进行相应处理
      // handle code
      e.printStackTrace();
    }
  }
}

运行时异常

继承自RuntimeException,编译时不会抛出,直到运行到那行代码才抛出,此时问题发生无法让功能正常进行,如数组下边越界,更多是由于调用者的原因(代码写得有问题,比如本应该是arr[i]写成了arr[i+1])或者引发了内部状态改变导致,异常抛出后可处理可不处理,编译让其通过,运行时强制停止,让调用者去处理。即方法头不用加throws,方法体内也不用catch。

public class Test {
    // 不用处理
    public void run1() {
        throws new RuntimeException();
    }

    public static void main(String args[]) {
        Test t = new Test();
        t.run1(); // 调用也不处理,程序终止
      
      // 调用时正确处理,程序继续
        try {
          t.run1();
        } catch (Exceptipon e) {
          // 实际开发肯定不能这样,必须进行相应处理
          // handle code
          e.printtStackTrace();
        }
    }
}

自定义异常类

public class MyException extends RuntimeException {
  // 构造函数一般用父类的
  MyException(String s) { super(s); }
}

// another file
public class Test {
  public void run() {
    if (/*expression*/) {
      throws new MyException("自定义异常") // 传入实参给了super(s)
    }
    else {
      // code...
    }
  }
  
  public static void main(String args[]) {
    Test t = new Test();
    try {
       t.run();
    } catch (RuntimeException e) {
      // handle code
      e.printStackTrace();
    }
   
  }
}

什么时候用try,什么时候用throws

  • 能自己解决的用try,比如数组下标越界,调用者可以事先作判断下标的范围,防止该异常发生。即使造成异常,程序终止,也可以通过修改代码解决。
  • 不能自己解决的,比如IO异常,文件没有被关闭,数据库连接异常,访问不存在的路径等,我们没有办法自己搞定,只能上报上级(throws),试想如果路径出错了,根本就没有这个文件。而又try-catch,捕获后程序正常运行,并没有把路径错误给暴露出去。(路径都错了后面的程序能正常运行吗?)这就叫“把异常给吃(隐藏)了”。相反,如果继续抛出,一直到程序终止,用户看到异常信息就知道是路径错了,需要改路径。这样的异常写代码的人根本无法处理,不是改代码就可以的,毕竟程序猿怎么改也可能有人把路径写错:)

异常的其他注意事项

  • try -catch还可搭配finally使用,无论捕获异常否,finally里面的内容必然或执行,一般用于关闭文件、关闭连接、释放资源等
  • 也可以不catch,只try-finally。比如某个函数可能抛出异常,我不想处理,但是又必须要把某件事给做了,这是就可以用这种结构。
  • throw了多少(n)个异常,就要catch多少(n)个异常。
  • 父类方法头若没有throws异常,子类方法覆盖父类时候,子类的方法头不能throw异常。
  • throw是确确实实抛出了一个异常,而throws是提醒、标注这儿可能出现异常,并没有实际抛出。

异常的一个形象的例子

上面说的什么时候用try,什么时候用throws还是很抽象的,我也不知带自己在说什么。和实际生活结合起来,看下面这个例子就豁然开朗了,为了直观,部分代码采用中文,注意这很不规范,仅为了便于理解异常。

// 老师用电脑上课

class 电脑蓝屏异常 extends RuntimeException {
    电脑蓝屏异常(String s) { super(s); }
}
class 电脑烧坏异常 extends RuntimeException {
    电脑烧坏异常(String s) { super(s); }
}
// 电脑烧坏时,午饭自己解决,抛出这个异常个老板,让老板给出解决方案
class 上报老板异常 extends Exception {
    上报老板异常(String s) { super(s); }
}
class Computer {
    // 电脑运行状态标志位,0位正常运行
    private int flag = 1;
    public void run() {
        if (flag == 1) {
            throw new 电脑蓝屏异常("你的电脑蓝屏啦!");
        } else if (flag == -1) {
            throw new 电脑烧坏异常("你的电脑烧坏啦!");
        } else {
            System.out.println("老师上课中...");
        }
    }
    public void reset() {
        // 重启后正常运行,标志位置0
        flag = 0;
        // 重启电脑
        System.out.println("电脑重启中...");
    }
}


public class Teacher {
    public static void main(String args[]) throws 上报老板异常 {
        Computer pc = new Computer();
        try {
            pc.run();
        } catch(电脑蓝屏异常 e) {
            System.out.println("同学们,电脑出了点小毛病,大家等几分钟就好了");
            // 蓝屏了可以自己处理,重启一下电脑就行,所以
            pc.reset();
            pc.run();
        } catch(电脑烧坏异常 e) {
            System.out.println("同学们,这节课我们不能继续上课了,自习");
            e.printStackTrace();
            // 烧坏了,没办法自己解决,要么拿去给修电脑的,要么上报给老板买个新的
            // 所以继续抛向上级
            throw new 上报老板异常("老板..电脑..坏了..需要买新的");
        }
    }
}
  • flag设置为1,说明电脑蓝屏了,运行以上代码,打印如下信息,可以看到,正确处理了异常后,老师又开始上课了。

同学们,电脑出了点小毛病,大家等几分钟就好了
电脑重启中...
老师上课中...

  • flag设置了-1,说明电脑烧坏了,会打印以下信息。抛出异常。

同学们,这节课我们不能继续上课了,自习
Test.电脑烧坏异常: 你的电脑烧坏啦!

at Test.Computer.run(Teacher.java:21)
at Test.Teacher.main(Teacher.java:39)
Exception in thread "main" Test.上报老板异常: 老板..电脑..坏了..需要买新的
at Test.Teacher.main(Teacher.java:50)
同学们,这节课我们不能继续上课了,自习

注意:以上代码虽然很多中文,但是可以直接编译运行成功的。因为默认编码方式是UTF-8。


by @sunhaiyu

2016.12.12

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

推荐阅读更多精彩内容

  • 导语 异常指的是在程序运行过程中发生的异常事件,通常是由硬件问题或者程序设计问题所导致的。异常处理提供了处理程序运...
    jerrwy阅读 483评论 0 2
  • 一、异常处理机制1、异常的祖先是Throwable,有如下两个子类:a、Error:表示错误,错误产生后程序员不能...
    坚持也是一种成功阅读 809评论 3 27
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,296评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,103评论 18 139
  • 个体心理学在心理和教育方面视野开阔,固然不会忽视外在环境的影响。所有的教育者都必须考虑到经济因素对儿童的影响。例如...
    美好jenny阅读 475评论 0 0