Java异常处理以及相关的面试题

Java错误与异常

异常的分类

1.错误与异常 基本介绍

Java分为Error和Exception,它们之间的区别
Error:程序发生错误,脱离程序员的控制,比如内存超出,非程序员编写的程序出现问题等,由Java虚拟机抛出错误
Exception:则分为受检异常 和 非受检异常

1.受检异常 直接继承于Exception,编写时不进行异常处理,则会出现错误
常见的比如IO异常,通常直接抛出异常等等

2.非受检异常(也称运行时异常) 直接继承于RuntimeException,编写时不报错误,通常参数出现问题时JVM抛出错误
常见的异常包括空指针,算数异常(除数为0)等等

2.异常发生处理

处理方式有两种:
(1)throws抛出

throws关键字,此关键字主要在方法的声明上使用,表示方法中不处理异常,而交给调用处处理。
格式:
返回值 方法名称()throws Exception{
}

(2)try···catch···finally捕获异常处理

try{
// 有可能发生异常的代码段
}catch(异常类型1 对象名1){
// 异常的处理操作
}catch(异常类型2 对象名2){
// 异常的处理操作
} ...
finally{
// 异常的统一出口
}

try+catch的处理流程
1、 一旦产生异常,则系统会自动产生一个异常类的实例化对象。
2、 那么,此时如果异常发生在try语句,则会自动找到匹配的catch语句执行,如果没有在try语句中,则会将异常抛出.
3、 所有的catch根据方法的参数匹配异常类的实例化对象,如果匹配成功,则表示由此catch进行处理。

finally
在进行异常的处理之后,在异常的处理格式中还有一个finally语句,那么此语句将作为异常的统一出口,不管是否产生
了异常,最终都要执行此段代码。

(3) 人为抛出异常

throw关键字表示在程序中明确地抛出一个异常,因为从异常处理机制来看,所有的异常一旦产生之后,实际上抛出
的就是一个异常类的实例化对象,那么此对象也可以由throw直接抛出。
代码: throw new Exception("自定义异常。") ;

3.常见的关于异常处理的面试题

1.上文说到的finally在不管有异常还是没有异常发生的情况下,最终都需要执行finally,那么什么情况下不执行finally?

两种情况:
非正常情况下:如断电,关闭程序等等,导致内存被清理,finally不执行
正常情况下:
try{
异常;
}catch(){
	System.exit(0);//人为因素,直接退出程序,finally不执行,参数0是正常退出,非0为非正常退出
}finally{
}

2.try-catch-finally 中哪个部分可以省略?

catchfinally可以省略其中一个 , catchfinally不能同时省略
注意:格式上允许省略catch, 但是发生异常时就不会捕获异常了,我们在开发中也不会这样去写代码.

3.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?什么时候被执行,在return前还是后?

finally中的代码会执行,在方法返回调用者前执行。
详解:
执行流程:
1. 先计算返回值, 并将返回值存储起来, 等待返回
2. 执行finally代码块
3. 将之前存储的返回值, 返回出去;
语言描述:try中的return语句不会立马返回调用者,而是记录下返回值待finally代码块执行完毕之后再向调用者返回其值,
然后如果在finally中修改了返回值,就会返回修改后的值。

需注意:
1. 返回值是在finally运算之前就确定了,并且缓存了,不管finally对该值做任何的改变,返回的值都不会改变
2. finally代码中不建议包含return,因为程序会在上述的流程中提前退出,也就是说返回的值不是trycatch中的值

4.对上面第3点的补充,finally返回具体的值还得看参数值的数据类型,如

try{
	int a = 10;
}catch{
	return null;
}finally{
	a = 20;
	retturn a;
}
答案:返回a的值为10
基本数据类型finally下仅仅把参数值进行复制,仍然返回的是原来的值
try{
	Person p = new Person();
	p.setAge(10);
}catch{
	p.setAge(20);
}finally{
	p.setAge(30);
}
System.ou.print(p.setAge(10));
答案:输出的是30
引用数据类型finally下保存的是引用的地址,栈中原地址对应堆中的值改变,再输出值也相应发生改变

5.列出你常见的运行时异常

- ArithmeticException(算术异常)
- ClassCastException (类转换异常)
- IllegalArgumentException (非法参数异常)
- IndexOutOfBoundsException (下标越界异常)
- NullPointerException (空指针异常)
- SecurityException (安全异常)

6.类ExampleA继承Exception,类ExampleB继承ExampleA。执行此段代码的输出是什么?
有如下代码片断:

try {
	throw new ExampleB("b")
} catch(ExampleA e){
	System.out.println("ExampleA");
} catch(Exception e){
	System.out.println("Exception");
}

答:输出:ExampleA。(根据里氏代换原则[能使用父类型的地方一定能使用子类型],抓取ExampleA类型异常的catch块能够抓住
try块中抛出的ExampleB类型的异常)

7.说出下面代码的运行结果。(此题的出处是《Java编程思想》一书)

class Annoyance extends Exception {}
class Sneeze extends Annoyance {}
class Human {
    public static void main(String[] args) throws Exception {
        try {
            try {
                throw new Sneeze();
            }
            catch ( Annoyance a ) {
                System.out.println("Caught Annoyance");
                throw a;
            }
        }
        catch ( Sneeze s ) {
            System.out.println("Caught Sneeze");
            return ;
        }
        finally {
            System.out.println("Hello World!");
        }
    }
}
答案是:
Caught Annoyance
Caught Sneeze
Hello World!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值