final/finally/finalize关键字对比

1. final

  final意味着“最后的、最终的”含义,final可以用来修饰类,方法和变量(成员变量或局部变量)。

1.1 修饰类

  当用final修饰类时,表明该类不能被其他类所继承。String是一个典型的final类型的类。

注意:final类中所有的成员方法都会隐式的定义为final方法。

1.2 修饰方法

把方法锁定,以防止继承类对其进行更改。如:枚举类中的equals()/clone()
此方法不能被重写,也不能在子类中重新定义同名同参的新方法

1.3 修饰变量

  final成员变量表示常量,只能被赋值一次,赋值后其值不再改变。
  当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;
  如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的,即地址的值不发生变化。 
  final修饰一个成员变量(属性),必须要显示初始化。这里有三种初始化方式,一种是在变量声明的时候初始化;第二种方法是在代码块中赋值;第三种方法是在构造函数中对这个变量赋初值。
  final修饰一个方法形参,一旦调用该方法(传入了实参),该参数值就不能再修改。

2. finally

  finally是在处理异常时搭配try/catch语句使用,并且附带一个语句块,在服务正常运行的情况下finally语句块最终一定会被执行(不管有没有抛出异常),经常被用于释放资源。

注意:只有与finally对应的try语句块得到执行的情况下,finally语句块才一定会执行。

    @Test
    public void test(){
        List<String> list = Arrays.asList("123", "12345", "1234", "4321", "1234567", "5678");

        //在执行try语句块之前就已经返回,finally不会执行
//        if(list.size() ==6 ){
//            return;
//        }

        //在执行try语句块之前抛出异常,所以try对应的finally语句并没有执行。
        //int i = 1/0;
        try {
            
            list.forEach(s -> {
                if (s.length() > 5) {
                    //模拟出现异常
                    throw new RuntimeException("foreach跳出循环");
                }
                System.out.println(s);
            });
        } catch (Exception e) {
            System.out.println("捕获异常" + e.getMessage());
        }finally{
            System.out.println("finally语句块执行!!!");
        }

    }

  当一个线程在执行 try 语句块或者 catch 语句块时被打断(interrupted)或者被终止(killed),与其相对应的 finally 语句块可能不会执行。
  如果finally中有return语句,,且已经执行到了try代码块,则不会执行try/catch中的return语句;如果finally中没有return,则执行完finally块中的代码,再执行try/catch中的return语句。

    public static void main(String[] args) {
        String s = testFinallyReturn();
        System.out.println(s); //finally
    }

    public static String testFinallyReturn(){
        List<String> list = Arrays.asList("123", "12345", "1234", "4321", "1234567", "5678");

        try {

            list.forEach(s -> {
                if (s.length() > 5) {
                    //模拟出现异常
                    throw new RuntimeException("foreach跳出循环");
                }
                System.out.println(s);
            });
            return "成功";
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return "异常";
        }finally{
            System.out.println("finally语句块执行!!!");
            //return "finally";
        }

    }

3. finalize

  finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),反射方式可以创建对象,所以一般是不需要程序员去实现finalize的。
  特殊情况下,需要程序员实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。
  使用finalize还需要注意一个事,调用super.finalize();
  一个对象的finalize()方法只会被调用一次,而且finalize()被调用不意味着gc会立即回收该对象,所以有可能调用finalize()后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会再调用finalize(),进而产生问题。 所以,不推荐手动调用finalize()方法,它跟析构函数不一样。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值