Java学习笔记之异常(一)

       Java的基本理念是“结构不佳的代码不能运行”。

       发现错误的理想时机是在编译阶段,也就是在运行程序之前。然而,编译期间并不能找出所有的错误,雨下的问题必须在运行期间解决。这就需要错误源能通过某种方式,把适当的消息传递给某个接受者——该接受者将指导如何正确处理这个问题。

       Java中的异常处理的目的在于通过使用少于目前数量的代码来简化大型、可靠的程序的生成,并且通过这种方式可以使你更加自信:你的应用中没有未处理的错误。

1.概念

        通常我们写代码时,当发现有错误时,可能会立即处理这个错误。但是当很多地方都出现了这个同样的错误后,我们会在错误出现的地方又进行立即处理。这就让代码重复了很多,而异常机制给我们提供了一种将错误源和处理错误相分离,使可读性更高、代码更简洁。

2.异常参数

       异常参数是指明错误发生的地方,然后就会抛出一个异常,为了让处理错误的代码知道是由哪个异常抛出的,通常会添加一些附加信息。       

throw new NullPointerException("something is null");

          当代码执行到上面一句话时,就会抛出异常,接下来异常处理机制就来接管程序了,所以这句代码也有类似返回的作用。

3.异常说明

       我们常常使用别人写好的类库,类库的编写者知道他的代码哪里跑出了异常,但是作为客户端的程序员并不知道,那么有何种方式能让客户端的程序员知道呢?异常说明就能解决这一问题,它属于方法声明的一部分,紧跟在形式参数列表之后。

       异常说明使用了附加的关键字throws,后面接一个所有潜在异常类型的列表,所以方法定义看起来像这样:

void f() throws Exception1,Exception2{}

           代码必须与异常说明保持一致,因为这关系到错误如何处理。如果方法里的代码产生了异常却没有进行处理,编译器会发现这个问题并提醒你:要么处理这个异常,要么就在异常说明中表明此方法将产生异常。也就是说有了异常,要么你自己处理掉了,要是不处理的话就告诉别人这儿有个异常让别人去处理,别既不处理又不告诉别人,那么这个异常就会一直留着,也就会出现bug了。通过这种自顶向下强制执行的异常说明机制,Java在编译时就可以保证一定水平的异常正确性。

        但是有个可以“作弊”的地方,就是虽然没有产生异常,但却告诉别人有异常。那么 别人使用你的代码时编译器就会强制他们“上当”了。

4.捕获异常

       要明白异常是如何被捕获的,必须首先理解“监控区域”的概念。它是一段可能产生异常的代码,并且后面跟着处理这些异常的代码。      

try {
//有可能抛出异常的地方
} catch (Exception1 e1) {
//处理异常Exception1
}catch(Exception2 e2){
//处理异常Exception2
}

          如果在方法内部抛出了异常(或者在方法内部调用的其他地方抛出了异常),这个方法将在抛出异常的过程中结束。要是不希望方法到此结束,可以在方法内部设置一个特殊的快的捕获异常。因为在这个块里“尝试”各种可能发生异常的方法调用,所以称为try块。抛出了异常就得进行处理(当然也可以抛出,让别人去解决)。这个“地点”就是异常处理程序,而且针对每个异常,得准备相应的处理程序。(异常不一样,解决方法自然不一样)异常处理程序紧跟在try块之后,以关键字catch表示。

        每个catch子句看起来就像是接受一个且仅接受一个特殊类型的参数(Exception以及子类)的方法。

        Java支持终止模型,在这种模型中,将假设错误非常关键,以至于程序无法返回到异常发生的地方继续执行。一旦错误被抛出,就表明错误已无法挽回,也不能回来继续执行。

        catch可以捕获多个异常,那么是按照什么样的规则进行匹配异常呢?Java使用的是一旦匹配到了合适的异常,就不再向下继续匹配了,所以范围越大的异常应该放在越下面。

5.使用finally进行清理

       对于一些代码,可能希望无论try块中的异常是否抛出,它们都能得到执行。这通常适用于内存回收之外的情况(因为回收由垃圾回收期完成)。为了达到这个效果,可以在异常处理程序后面加上finally子句。

       对于finally子句,当涉及到break或者continue或者return语句时候,finally子句也会得到执行。

下面通过一个例子来结束上面几点:

public class ExceptionBlog {
// 实现a/b的功能
public static int divide(int a, int b) throws ArithmeticException
// 异常说明
{
// 当除数为0时,抛出异常
if (b == 0)
throw new ArithmeticException("除数不能为0");
return a / b;
}
/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
// 测试一个没有发生异常的情况,15/3
try {
divide(15, 3);
System.out.println("15/3="+divide(15,3));
}
//测试异常匹配的规则
catch (ArithmeticException e) {
System.out.println("ArithmeticException已被处理!");
} catch (Exception e) {
System.out.println("Exception已被处理!");
}
//测试finally是否总是会被执行
finally {
System.out.println("finally总是被执行!");
}
// 测试一个会出现问题的情况,5/0
try {
divide(5, 0);
//异常一旦发生,下面的代码不会被执行!
System.out.println("我会不会被执行呢?");
} catch (ArithmeticException e) {
System.out.println("ArithmeticException已被处理!");
} catch (Exception e) {
System.out.println("Exception已被处理!");
} finally {
System.out.println("finally总是被执行!");
}
}
}

Output:

15/3=5

finally总是被执行!

ArithmeticException已被处理!

finally总是被执行!

其实上面这段代码中的方法,就算不进行异常说明编译器也不会提示错误,至于这个原因,下篇博客再介绍。

finally其实不总是执行,有一个特例,那就是在有System.exit(int status)这个方法时,这个方法表示终止Java虚拟机,0表示正常终止,非0表示不正常终止。另外这个方法和Runtime.getRuntime().exit()方法等效。

6.总结

    1)异常机制是一种将错误和处理错误分离的一种方法。

    2)在Java中通过throw抛出异常,通过异常说明告诉别人这儿有异常需要他处理。

    3)使用try块尝试可能发生异常的代码,使用catch捕获发生的异常,捕获遵循一旦捕获到了异常,就不再继续捕获的原则。

    4)finally块基本总会执行,可以使用进行一些清理工作。不过也有特殊情况。


转载于:https://my.oschina.net/992257586/blog/351151

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值