java 中的异常处理

1、什么是异常怎么处理异常

两个数相除的小代码会遇到三个问题

  • 参数个数不对 java.lang.ArrayIndexOutOfBoundsException
  • 参数类型不对 java.lang.NumberFormatException
  • 被除数为零 java.lang.ArithmeticException

对这些问题的处理如下

public class ExceptionDemo {
    public static void main(String args[]) {
        System.out.println("---------计算开始---------");
        try { //在这里捕捉异常,将其与 catch 括号中的异常进行配对,配上了就跳出 try ,直接执行 catch 里的内容
            String str1 = args[0];
            String str2 = args[1];
            int i = Integer.parseInt(str1);
            int j = Integer.parseInt(str2);
            int temp = i /j;
            System.out.println("两个数相除的结果是:"+temp);
        }catch(ArithmeticException e) {//被除数为0,算术问题匹配对象
            //System.out.println("算术异常:"+e);
            e.printStackTrace();
        }catch(NumberFormatException e){//用户输入的不是数字,数字类型匹配对象
            System.out.println("数字转换异常:"+e);
        }catch(ArrayIndexOutOfBoundsException e){//用户输入的数字个数不对
            System.out.println("数组越界异常:"+e);
        }finally { //不管有没有匹配的异常对象都输出这个
            System.out.println("处理完成");
        }
        System.out.println("---------计算开始---------");
    }
}

2、异常类的继承结构

  • 前面接触到了三个异常:ArithmeticException、NumberFormatException、ArrayIndexOutOfBoundsException
    注意
以上三个类都是继承了 java.lang.Exception 类
而 Exception 类继承了 Throwable 类
Throwable 类有两个子类 Error、Exception
Exception:一般表示的是程序中出现的问题,可以直接使用 try...catch 处理。
Error:一般指的是 JVM 错误,程序中无法处理。如执行 java A
一般将 Exception 与 Error 统称为异常,前面的三个异常类都是继承 Exception 类。
可以使用 System.out.println(); 方法输出异常
也可以在 Exception 的子类  AclNotFoundException 中找到  printStackTrace() 方法,该方法可以进行输出

3、异常的处理机制

**整个java处理异常中,应用了java的多态性

  • 一旦产生异常,会在 try 中捕捉异常创建一个异常类的实例化对象
  • 将捕捉到的异常对象与 catch 语句中的各个异常类型进行匹配,如果配对成功就执行 catch 里的代码

多态* 子类的实例化对象可以直接使用父类的对象进行接收。
所有的异常类都是 Exception 的子类,所以所有的异常对象都可以用 Exception 进行接收。
因为程序的顺序执行,所以 Exception 的捕捉要放在最后:
在异常处理中,捕获更粗的异常要放在捕获更细的异常之后

...
catch(Exception e){
    e.printStackTrace();
}
...

如果所有异常的处理方式一样,可以只用 Exception 来捕获,这属于“偷工减料”
问题:
直接使用 Exception 捕获异常简单粗暴,那能不能用 Exception 的父类 Throwable 进行捕获呢?
答:是可以捕获的,但是 Throwable 有两个子类 Exception 和 Error ,程序在运行中只会抛出 Exception 的子类,这么做的话目的不够明确。

4、throws 与 throw 关键字

1、定义一个方法时可以用 throws 关键字声明,表示此方法不处理异常,交异常给方法调用处进行处理。

class Math {
    public int div(int i,int j)throws Exception {//throws 关键字声明方法,抛出异常
        int temp = i/j ;
        return temp ;
    }
}

public class ThrowsDemo {
    public static void main(String args[]) {
        Math math = new Math();
        try {
            System.out.println("两个数相除结果:"+math.div(10, 2));
        }catch(Exception e) {
            e.printStackTrace();
        }
        }
}

主方法也可以抛出异常而不处理,这种情况是交给 JVM 处理,出现异常将导致程序中断
2、throw 关键字是用来人为的手工抛出异常的

public class ThrowDemo {
    public static void main(String args[]) {
        try {
            throw new Exception("自己抛出异常");
        }catch(Exception e) {
            e.printStackTrace();
        }
    }
}

5、在开发中,一般都是将 try...catch...finaly、throw、throws 综合起来使用的。

设计一个相除的方法  
要求必须打印“计算开始”、“计算结束”信息  
如果有异常刚交给调用处处理  
//开发模式一般会这样使用异常处理
class Mathadd{
    public int div(int i,int j)throws Exception {
        System.out.println("**** 计算开始 ****");
        int temp = 0 ;  
        try{
            temp = i/j ;
        }catch(Exception e){
            throw e ; //抛出异常给调用处处理
        }finally { 
            // 不管是否有异常都执行的统一出口,
            // 在开发中经常使用,释放资源或者是干嘛
            System.out.println("**** 计算结束 ****");
        }
        return temp ;
    }
}
public class TryThrowDemo {
    public static void main(String args[]) {
        Mathadd mathadd = new Mathadd() ;
        try {
            System.out.println("除法操作:"+mathadd.div(10, 0));
        }catch(Exception e) {
            System.out.println("异常产生:"+e);
            //e.printStackTrace();
        }
    }
}

6、Exception 类与 RuntimeException 类的区别

以下代码用到了 Integer 类下的 parseInt() 方法,查看文档中该方法

public class RuntimeExceptionDemo {
    public static void main(String args[]) {
        String string = "123" ;
        int temp = Integer.parseInt(string) ;
        System.out.println("乘方操作:"+(temp*temp));
    }
}

Integer 类在 java.lang 包中
parseInt() 方法的定义如下
public static int parseInt(String s) throws NumberFormatException
该方法使用了 throws 关键字抛出了异常,但是在以上代码中使用的时候并没有处理异常。
再看看 NumberFormatException 异常类,可以发现其是 RuntimeException 的孙类。
所以如果抛出的是 RuntimeException 的子类的异常可以不用处理,处理机制直接交给JVM处理了

7、自定义异常

自定义的异常只要继承 Exception 类即可

class MyException extends Exception {
    public MyException(String msg) {
        super(msg) ;
    }
}
public class DefaultException {
    public static void main(String args[]) {
        try {
            throw new MyException("自己定义的异常") ;
        }catch (Exception e) {
            System.out.println(e);
        }
    }
}

8、断言

断言是假设一个执行结果,如果实际执行结果不对就返回错误

public class Test {
    public static void main(String args[]) {
        int x[] = {1,2,3} ; //定义一个长度为3的整型数组 
        assert x.length == 0 : "数组的长度不为0"; //此处断言数组的长度为0并且作出错误提示
    }
}

在 eclipse 中执行,如果没有设置,断言是不会起效果的。
在黑窗口中执行,让断言起效果的方式是java -ea Test 或者java -enableassertions Test

  • 虽然断言返回的是 boolean 值,但是不能作为条件判断语句
  • 不提倡过多使用断言

9、小结

1、异常出现之后,如果没有进行处理,则会让整个程序中断执行。
2、使用 try...catch 和 try...catch...finally 可以处理异常,finally 将作为异常的统一出口。
3、一个异常处理中可以同时出现多个 catch ,但是捕获更粗的异常要放在捕获更细的异常之后。
4、在异常中最大的类是 Throwbale ,分为两个子类:Exception、Error

  • Exception 是程序可以自己处理的异常。
  • Error 是 JVM 错误,一般程序无法处理。

5、处理异常可以直接用 Exception ,但是最好分开各个异常捕获处理,不要偷工减料。
6、产生异常,会在 try 中实例化一个异常的对象,此对象与 catch 中声明的对象类型进行匹配,匹配成功就执行 catch 中的代码,如果 一直无法匹配成功,则程序中断。
7、throws 与 throw 的区别

  • throws 在方法声明时使用,抛出异常给方法调用处处理。
  • throw 是人为地抛出异常。

8、Exception 与 RuntimeException 的区别

  • Exception 一定要对其抛出的异常处理。
  • RuntimeException 可以不对其抛出的异常处理,建议要处理。

9、在开发中处理异常一般都将 try...catch...finaly、throws、throw 用上。
10、自定义异常只需要继承 Exception 或其子类即可。
11、断言不太重要。

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

推荐阅读更多精彩内容

  • 大家好,我是IT修真院郑州分院第6期的学员李亚衡,一枚正直纯洁善良的JAVA程序员 今天给大家分享一下,修真院官网...
    一筒君阅读 353评论 0 0
  • 如果我们制作一个计算器程序,当用户输入的除数为0时,程序将会崩溃直接退出,那么该程序的用户体验将会非常差。我们应该...
    yuluo阅读 578评论 0 1
  • 八、深入理解java异常处理机制 引子try…catch…finally恐怕是大家再熟悉不过的语句了, 你的答案是...
    壹点零阅读 1,526评论 0 0
  • 世界上有一朵花, 遇见了她的奇葩, 奇葩偏好牛粪, 凭着睿智才情, 吸引来一群奇花, 他们引吭高歌,酒中把舞, 奇...
    无味丸子阅读 130评论 0 0
  • “圣母癌”患者的正确治疗方式 ◎迟小钝 博爱姑娘最近心事重重,眉头皱得都可以夹死螨虫了,放眼望去,愁云惨淡的脸上只...
    税颖阅读 838评论 0 1