美文网首页
谈谈 final

谈谈 final

作者: 巴巴11 | 来源:发表于2020-04-16 22:07 被阅读0次

    1 lambda访问外部变量必须是final的。

    lambda本质是一个匿名内部类。
    
    匿名内部类无法访问外部类方法的局部变量(每个方法都有自己的栈帧,匿名内部类的执行和外部方法可能不在一个线程里,当访问局部变量时,可能该变量已经被回收了,final类型的局部变量在lambda匿名类里其实是局部变量的一个拷贝)。
    
    局部变量是存储在栈上的,而栈上的内容在当前线程执行完成之后就会被GC回收掉。
    lambda表达式最终被处理为一个额外的线程去执行。绝对不是上面提到的线程。如果上面的线程执行完了,而这个线程又使用到了上面提到的局部变量会出现错误。
    
    外部类的局部变量,只能通过匿名内部类的构造方法传进去。
    
    lambda是拥抱函数式编程,而函数式编程本身不应该为函数引入状态,final修饰的变量不可修改也是迎合了这一点。
    

    2. final修饰变量,类,方法

    • 被final修饰的类不可以被继承
    • 被final修饰的方法不可以被重写
    • 被final修饰的变量不可变(被final修饰的变量,不可变的是变量的引用,而不是变量的内容)
    • 被final修饰的常量,在编译阶段会存入调用类的常量池中

    final修饰基本类型变量
    当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变
    final修饰引用类型变量

    当使用final修饰引用类型变量时,它保存的仅仅是一个引用,final只能保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以改变

    package com.mxixm.spring.mvc;
    
    import java.util.Arrays;
    
    public class Main1 {
    
        public static void main(String[] args) {
            /**
             * final修饰基本类型变量
             * 当使用final修饰基本类型变量时,
             * 不能对基本类型变量重新赋值,因此基本类型变量不能被改变
             */
            final int i = 1;
    //        i = 2; // no....
    
            /**
             * final修饰引用类型变量
             * 当使用final修饰引用类型变量时,
             * 它保存的仅仅是一个引用,
             * final只能保证这个引用类型变量所引用的地址不会改变,
             * 即一直引用同一个对象,但这个对象完全可以改变
             */
            final int[] arr = new int[]{1, 2};
            System.out.println(Arrays.toString(arr));
            Arrays.sort(arr); //
            System.out.println(Arrays.toString(arr));
    //        arr = null; // no....
            arr[0] = 10; // yes...
    
            final InnerCls cls = new InnerCls();
            cls.name = "test"; // yes...
    //        cls == new InnerCls(); // no....
        }
    
        static class InnerCls {
            String name;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:谈谈 final

          本文链接:https://www.haomeiwen.com/subject/widjvhtx.html