java异常代码c0000374_Java异常处理

为什么需要异常?

以前用C写数据结构的时候,总有这样一个烦恼:比如写栈的Pop函数,除了在函数体中完成出栈的操作,还要使用一个返回值,表示出栈操作是否成功进行。

但是呢,为了将出栈的值返回给调用者,就要用return语句。但是return又被函数状态值占用了,于是只能用指针了,这就必须给pop函数加一个指针参数,用起来很不方便。

java内置了异常机制,函数可以尽管执行,如果出现了什么意外的事,异常就会发生,我们的程序可以通过异常来处理这些意外。这将函数的功能与函数的执行状态分离了,编写的代码更清晰。

java异常的继承结构和分类

java中所有的异常都是Throwable的子类,下面又分2个分支:Error和Exception。

Error不用我们管,当Error发生时,你应该责怪java自身。java运行时,本身系统出了问题,这并不是你的代码的问题。所以我们根本不用管Error这个分支。 Error一般很少发生。

Exception又可以分为2类:RuntimeException和 非RuntimeException异常。

RuntimeException异常(非检查异常)发生时,一定你的的代码写的有问题,具体说是代码的逻辑有问题,而不是语法问题,语法问题在编译时就会提示你。

比如使用了空指针,数组下标越界,无限循环造成的StackOverflow等。当这些异常发生时,你应该尽量去修改你的代码,而不是想着去捕获他们。这些都是可以避免的。

非RuntimeException异常(检查异常,图中深蓝色标记的),与RuntimeException相反,他们都是程序员不可避免的,比如出现执行一个IO操作,电脑可能没磁盘容量了,或者用户移除了IO设备。数据下载时,网络断开了......

非RuntimeException异常是java异常处理中我们最关心的异常分支。

3870d8a880c3baf716871450c6035120.png

另外:RuntimeException异常和非RuntimeException异常一个明显的区别是,如果使用Eclipse,编译器会提醒你,并强制你处理

非RuntimeException异常,而对于RuntimeException异常,编译器不会提醒你处理。

UIManager.setLookAndFeel是Swing中设置UI感官的方法,它会抛出:ClassNotFoundException等非RuntimeException异常

fe61a0927f89e1f9f5690a51a530285c.png

StringIndexOutOfBoundsException 是一个RuntimeException,Eclipse不会提醒你.

1088691f7e1568b5760893afe094bbc9.png

异常发生后会怎么样

首先要明确,异常是在方法内产生的,因为方法用来操作数据,操作数据就可能发生异常。

我们还要理解的是函数调用栈:函数的调用时以栈的形式管理的,层级调用,依次入栈。

当在某一个代码块中发生异常后,JVM就会去这个代码块层次中寻找异常处理器(形如:try....catch...finally),如果找到了相应的处理器,则执行处理器的代码,然后跳出,执行处理器后面的代码。如果在当前方法中找不到合适的处理器,则此方法终止执行(return 语句也不会执行),JVM递归的到这个函数的调用函数去找

一旦找到异常处理程序,则在那一层处理掉这个异常,然后,在那一层往后执行(异常在哪里被处理掉,执行流就在那里往后执行)。

如果一直回溯到栈底都没有异常处理程序,则此线程终止。

下面来看一个小例子:

public static void foo1() throwsException

{

foo2();

}private static void foo2() throwsException

{throw newException();

}public static voidmain(String []args)

{try{

foo1();

}catch(Exception e){//TODO Auto-generated catch block

e.printStackTrace();

}

}

4fb865881a402a5c3ed2e9fb2ae29d50.png

我们可以使用异常的printStackTrace()方法打印异常的堆栈信息。

c4db33a1020210b04d91df293a6ad967.png

在代码中处理异常

主要要会用try...catch....finally语句。

fd9aa24d4580de7cbd00e8a3bc5e0c72.png

1、catch(XXXException e)    ,在异常发生,catch匹配到XXXException时,运行时系统就会将生成的异常对象赋值给变量e.这样,通过对异常变量e分析,就可以获取异常的详细信息异常。

2、finally主要用在异常处理器的收尾工作。关闭一些资源。比如一个文读一个件,无论成功读取,还是读取时发生异常了,最后都要关闭文件流,这个时候就要用到finally。

3、catch语句的顺序应该从具体异常到广泛异常,从特殊异常到一般异常。

try{

file.read();

}catch(EOFException e){ //EOFException是IOException的子类

}catch(IOException e){ //IOException是Exception的子类}catch(Exception e){

}

4、同一个处理块处理多个异常

try{

...

}catch(AException |BException e)

{

System.out.println("抛出AExcpetion或者BException 都会执行这个代码块")

}

5、如果子类复写了父类中一个会抛异常的方法,那么,子类的这个方法应该抛出父类相同的异常,或者是子类异常,或者不抛异常,总之要在父类异常的可控范围内。可以想一想,如果不遵循这个规则的话,那么多态就无法实现了。

6、如果一个方法出现异常了,也没处理,它会中断执行,不会有返回值。

7、如果在正常离开try是因为return,break ,continuer语句,则会先去执行finally,再执行他们。

在方法中抛出异常

如果一个方法中会抛出异常,并且这个方法本身不去处理,让调用者去决定如何处理。那么,它就必须使用throws语句在函数头进行声明它可能抛出的所有异常类型。

声明的作用就是告知调用者:我可能会抛出一个异常,你需要做好准备。

下面是Swing 中UIManager类中的setLookAndFeel的函数头,它声明自己会抛出的异常。

public static void setLookAndFeel(String className)throwsClassNotFoundException,

InstantiationException,

IllegalAccessException,

UnsupportedLookAndFeelException

{

//...

}

主动抛出异常

使用throw 语句,后接一个异常对象。抛出一个异常对象。

下面是一个将参数字符串转为大写的自定义函数。

private String toUpper(String s) throwsException

{if(s==null)throw new Exception("Paramter is null");else if(s.equals(""))throw new Exception("Empty String");else

returns.toUpperCase();

}

处理异常,但又抛出异常

有时候,一个方法需要对发生的异常进行过滤,或者对调用者隐藏某些异常,只抛出调用者能理解的异常,那么,它就要对异常进行捕获处理,然后适当抛出。

例子函数:打印一个字符串的第一个字符

private voidprintFirst(String s)

{try{

System.out.println(s.charAt(0));

}catch(NullPointerException e)

{throwe; //捕获到异常,然后抛给调用者

}catch(StringIndexOutOfBoundsException e)

{//do nothing。自己处理,不通告调用者。

}

}

定义自己的异常

异常的常用方法

e.getMessage()                打印异常的详细信息

e.printStackTrace()           打印异常的跟踪栈

e.getLocalizedMessage()         异常的本地化描述

class MyException extendsException

{publicMyException()

{

super();

}publicMyException(String msg)

{super(msg);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值