# 六、final
# 1. 不变性
如果对象在被创建后,状态就不能被修改,那么它就是不可变的。
- 对于不可变对象,一定是线程安全的。
# 2. final 的作用
- 类防止被继承
- 方法防止被重写
- 变量防止被修改
- 天生线程安全
# 3. final 三种用法
# 3.1 修饰变量
- 被 final 修饰的变量,意味着值不能被修改。如果变量是对象,那么对象的引用不能变,但是对象自身的内容依然可以变化。
# ① final instance variable(类中的 final 属性)
赋值时机:
- 声明变量时等号右边直接赋值
- 构造函数中赋值
- 初始化代码块中赋值
- 不能不赋值
# ② final static variable(类中的 static final 属性)
赋值时机:
- 声明变量时直接等号赋值
- static 静态代码块赋值
- 不可用普通初始代码块赋值
# ③ final local variable(方法中的 final 变量)
赋值时机:
- 使用变量前必须先赋值
# 为什么要规定赋值时机?
1. 不赋值的话默认就是 null 了,又因为 final,后面又改变不了了,就只能是 null 了。
# 3.2 修饰方法
- 构造方法不允许 final 修饰。
- 不可被重写(static 也是,static 不是重写,而是毫无关系)。
# 3.3 修饰类
- 不可被继承(如 String)。
# 4. 注意点
- 被 final 修饰的变量,意味着值不能被修改。如果变量是对象,那么对象的引用不能变,但是对象自身的内容依然可以变化。
- 明确知道不可变就加 final。
- final 修饰 String 的话,如果编译器可以判断它是值,那么会直接放到常量池当中。
# 5. 不变性和 final 的关系
不变性并不意味着简单使用 final 修饰就是不可变
- 对于基本数据类型,确实被 final 修饰后就具有不变性
- 但是对于对象类型,需要该对象保证自身被创建后,状态永远不会变才可以。
- 一个 final 对象必须里面所有的属性都是 final 的这个对象才是不可变的。
# 6. 栈封闭
在方法里面新建的局部变量,实际上是存储在每个线程私有的栈空间,而每个栈的栈空间是不能被其他线程所访问到的,所以不会有线程安全问题。这就是“栈封闭”技术,是“线程封闭”技术的一种情况。