异常

 异常的分类

Error(错误): 是程序无法处理的错误。这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时、系统崩溃、虚拟机错误、动态链接失败等,这些错误无法恢复或者不可能捕捉,将导致应用程序中断,Error不需要捕捉。OutOfMemoryError\StackOverflowError。

Exception(异常) :是程序本身可以处理的异常。

  • 受检查的异常(checked exceptions)粉色,其必须被 try{}catch语句块所捕获,或者在方法签名里通过throws子句声明.受检查的异常必须在编译时被捕捉处理,命名为 Checked Exception 是因为Java编译器要进行检查,Java虚拟机也要进行检查,以确保这个规则得到遵守。FileNotFoundException位于java.io.IOExcption下,当试图打开指定路径名表示的文件失败时,抛出此异常
  • 运行时异常(runtime exceptions)绿色,需要程序员自己分析代码决定是否捕获和处理,比如 空指针,被0除..ClassCastException(当试图将对象强制转换为不是实例的子类时,抛出该异常),NullPointException(当应用程序试图在需要对象的地方使用null时,抛出异常),IndexOutOfBoundsException(指示某排索引超出范围时抛出),

异常处理方式

对于异常的处理方式有两种分别为:

  •           捕捉 try{}catch{}finally{}
  •           声明 throws

两者区别:

      对于try{}catch{}finally{}而言,用户可能确定知道代码会出现相关的异常,把有可能出现问题的地方放到try中去执行,如果一旦出现异常,立刻终止当前代码的继续执行,转而去执行catch{}里面的内容。对于这类异常用户已经处理了,不会在向上抛出。

      对于throws而言,一般使用在方法名的后面,使用throws关键字的时候,一般是开发者不确定出现什么异常或者出现异常的情况可能有多种。这时开发者在方法后面加throws关键字抛出相关的异常。对于调用该方法的其它开发者者必须捕获这个异常或者继续throws这个异常,把这个异常传递下去,自己不处理,交给其对应的父类去处理。

如果是多线程就用Thread.run()抛出,如果是单线程就用main()方法抛出。

throw关键字和throws关键字

  •     throw一般用于方法中,抛出用户自定义的异常如 throw new MyException("用户自定义异常")。
  •     throws是用在方法名的后面,通知使用该方法的人,当前方法有可能抛出异常。

throws和throw的区别(面试题)

throws

  • 用在方法声明后面,跟的是异常类名
  • 可以跟多个异常类名,用逗号隔开
  • 表示抛出异常,由该方法的调用者来处理
  • throws表示出现异常的一种可能性,并不一定会发生这些异常

throw

  • 用在方法体内,跟的是异常对象名
  • 只能抛出一个异常对象名
  • 表示抛出异常,由方法体内的语句处理
  • throw则是抛出了异常,执行throw则一定抛出了某种异常

使用异常的注意事项:

  • 先捕获子类,再捕获基类
  • 尽早抛出异常,同时对捕获的异常进行处理
  • 可以根据实际的需求自定义异常类,这些异常类只要继承自Exception类即可
  • 异常能处理就处理,不能处理就抛出

异常处理的执行顺序(针对try{}catch{}finally{}而言)

try(....){

}catch(....){

}finally(...){

}

t满足try的条件的执行try后面花括号的语句

不满足,被catch中语句捕获到的执行catch花括号的语句

没有被catch捕获到或者catch执行完毕后和try执行完毕后都要执行finally中的语句

一般来说finally中的方法都是会被执行的,其中finally中很大程度上用于资源的释放。

a、finally中的代码总是会执行吗?

答:no,

如果一个方法内在执行try{}语句之前就已经出现异常,会直接结束,那么finally语句指定不会执行了。因为它根本没有进入try语句中

如果在一个try语句中调用System.exit(0);方法,那么就会退出当前java虚拟机,那么finally也就没有执行的机会了

b、finally在return之前执行还是在return之后执行?

 答:很多人可能会说在return执行之前执行。我的答案是在return中间执行,是不是很特别,请按下面的例子:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

package com.yonyou.test;

 

 

class Test{

 

  public static void main(String[] args) {

      System.out.println(method());

     }

  public static int method(){

      int x=1;

      try{

          return x;

      }catch(Exception e)

      {

          return 0;

      }finally{

          ++x;

      }

       

  }

    }

 正确答案是:1

首先程序在执行到try{}语句中的return方法后,就会先返回相应的值,并把相应的值存储在一个临时栈中去保存这个结果。这时临时栈中存储的值为1。但是程序不会立刻返回,转而回去执行finally中的方法,++x,在finally执行完后,方法全部执行完,这时会再次调用return方法,注意这时不在是返回值,而是告诉主调程序,被调程序已经执行完了,你可以接着去执行你主程序的其它方法了。但是请注意,此时返回的值还是原来保存在临时栈中的值1。

 为了更好的理解这个问题,我们看下面的程序:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

package com.yonyou.test;

 

 

class Test{

 

  public static void main(String[] args) {

      System.out.println(method());

     }

  public static int method(){

      try{

          return 1;

      }catch(Exception e)

      {

          return 0;

      }finally{

          return 2;

      }

       

  }

    }

 正确答案是:2

这里仅仅需要注意的是在try{}语句中执行到return 1 会在临时栈中存储值为1的变量。接着回去执行finally里面的内容,这时执行finally中的return 2;方法,临时栈中的值就是变为 2,会覆盖原来临时栈中的值1.所以它的返回值为2。

return有两个作用:程序结束、更新返回值

 c、finally方法是必须的吗?

 不是,开发者可以根据自身的情况去决定是否使用finally关键字。

在异常处理中,若try中的代码可能产生多种异常则可以对应多个catch语句,若catch中的参数类型有父类子类关系,此时应该将子类放在前面,父类放在后面。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值