java面试之异常捕获

1、自定义异常捕获函数



2、final、finally和finalize

2.1、final

Final可以用于成员变量(包括方法参数),方法、类。

Final成员

  • 作为变量

变量一旦被初始化便不可改变(对于基本类型,指的是值不变;对于对象类型,指的是引用不变),初始化只可能在两个地方:定义处和构造函数。

  • 作为方法参数

对于基本类型,定义成final参数没有什么意义,因为基本类型就是传值,不会影响调用语句中的变量;对于对象类型,在方法中如果参数确认不需要改变时,定义成final参数可以防止方法中无意的修改而影响到调用方法。

Final方法

  • 不可覆写
  • 编译器将对此方法的调用转化成行内(inline)调用,即直接把方法主体插入到调用处(方法主体内容过多的时候反而会影响效率)

Final类

  • 不可继承

2.2、finally

异常处理关键字,finally中的主体总会执行,不管异常发生是否。

2.2.1、当try中有return时执行顺序

return语句并不是函数的最终出口,如果有finally语句,这在return之后还会执行finallyreturn的值会暂存在栈里面,等待finally执行后再返回)

2.2.2、return和异常获取语句的位置

  • 情况一(try中有return,finally中没有return)
public class TryTest{
    public static void main(String[] args){
        System.out.println(test());
    }
 
    private static int test(){
        int num = 10;
        try{
            System.out.println("try");
            return num += 80;
        }catch(Exception e){
            System.out.println("error");
        }finally{
            if (num > 20){
                System.out.println("num>20 :  "+ "num");
            }
            System.out.println("finally");
        }
        return num;
    }
}

输出结果: try
num>20 : 90
finally
90
解析: return num += 80 ”被拆分成了“ num = num+80 ”和“ return num ”两个语句 ,线执行try中的“num =num+80”语句,将其保存起来,在try中的”return num“执行前,先将finally中的语句执行完,而后再将90返回。

  • 情况二(try和finally中均有return)

<span style="font-size:10px;">public class TryTest{
    public static void main(String[] args){
        System.out.println(test());
    }</span><span style="font-size: 14px;">
</span><span style="font-size:10px;">    private static int test(){
        int num = 10;
        try{
            System.out.println("try");
            return num += 80;
        }catch(Exception e){
            System.out.println("error");
        }finally{
            if (num > 20){
                System.out.println("num>20 :  "+ "num");
            }
            System.out.println("finally");
            return 100;
        }
    }
}</span>

输出结果: try

num>20 : 90
finally
100

解析: try 中的 return 被”覆盖“掉了,不再执行。

  •  情况三(finally中改变返回值num)

public class TryTest{
    public static void main(String[] args){
        System.out.println(test());
    }
 
    private static int test(){
        int num = 10;
        try{
            System.out.println(try);
            return num;
        }catch(Exception e){
            System.out.println(error);
        }finally{
            if (num > 20){
                System.out.println(num>20 :  + num);
            }
            System.out.println(finally);
            num = 100;
        }
        return num;
    }
}
输出结果: try

finally
10

解析:虽然在finally中改变了返回值num,但因为finally中没有return该num的值,因此在执行完finally中的语句后,test()函数会得到try中返回的num的值,而try中的num的值依然是程序进入finally代码块前保留下来的值,因此得到的返回值为10并且函数最后面的return语句不会执行。

  • 另外一种情况:将num的值包装在Num类中

<span style="font-size:10px;">public class TryTest{
    public static void main(String[] args){
        System.out.println(test().num);
    }
 
    private static Num test(){
        Num number = new Num();
        try{
            System.out.println(try);
            return number;
        }catch(Exception e){
            System.out.println(error);
        }finally{</span><span style="font-size: 14px;">
</span><span style="font-size:10px;">            if (number.num > 20){
                System.out.println(number.num>20 :  + number.num);
            }
            System.out.println(finally);
            number.num = 100;
        }
        return number;
    }
}
class Num{
    public int num = 10;
}</span>

输出结果: try

finally
100

2.2.3、简单地总结如下:

try语句在返回前,将其他所有的操作执行完,保留好要返回的值,而后转入执行finally中的语句,而后分为以下三种情况:

情况一:如果finally中有return语句,则会将try中的return语句”覆盖“掉,直接执行finally中的return语句,得到返回值,这样便无法得到try之前保留好的返回值。

情况二:如果finally中没有return语句,也没有改变要返回值,则执行完finally中的语句后,会接着执行try中的return语句,返回之前保留的值。

情况三:如果finally中没有return语句,但是改变了要返回的值,这里有点类似与引用传递和值传递的区别,分以下两种情况,:

  • 如果return的数据是基本数据类型,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。
  • 如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。

2.3、finalize

类的Finalize方法,可以告诉垃圾回收器应该执行的操作,该方法从Object类继承而来。在从堆中永久删除对象之前,垃圾回收器调用该对象的Finalize方法。注意,无法确切地保证垃圾回收器何时调用该方法,也无法保证调用不同对象的方法的顺序。即使一个对象包含另一个对象的引用,或者在释放一个对象很久以前就释放了另一个对象,也可能会以任意的顺序调用这两个对象的Finalize方法。如果必须保证采用特定的顺序,则必须提供自己的特有清理方法。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值