龙空技术网

Java 中 final 关键字详细介绍

MFZ 126

前言:

而今大家对“java中的关键字”大致比较讲究,咱们都需要剖析一些“java中的关键字”的相关文章。那么小编同时在网摘上收集了一些关于“java中的关键字””的相关资讯,希望兄弟们能喜欢,各位老铁们一起来学习一下吧!

本文旨在介绍 final 关键字。

final 在 java 中的作用

1)final 修饰类

被修饰的类叫最终类(也叫不可变类),该类不能被继承,即不会有子类;

被修饰的类中的所有方法都自动的成为 final 方法,但是实例字段不会自动成为 final 修饰的字段;

2)final 修饰方法

修饰的方法不能被子类重写;

3)final 修饰成员变量

被修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改;

被修饰的字段必须在构造对象时初始化,即实例化对象后这个字段就已经有值了,且之后不可再改变;

final 在 java 多线程中的作用

java 编译器和电脑处理器都会对程序指令进行重排序,达到效率最大化。

而对于被 final 修饰的成员变量,java 编译器和电脑处理器会遵守以下两个重排序规则

1)在构造方法内对 final 变量的写入操作,与之后把构造出来的对象的引用赋值给引用变量操作,这两个操作之间的顺序不能重排序;

2)初次读一个包含 final 变量的对象的引用操作,与初次读该对象的 final 变量操作,这两个操作之间的顺序不能重排序;

对 final 变量写操作的重排序规则

1)JMM 禁止编译器把 final 变量重排序到构造函数之外;

即必须对 final 变量初始化之后才能跳出构造函数,之后才能把该对象的引用赋值给引用变量;

2)编译器会在 final 变量之后,退出构造函数之前,插入一个 StoreStore 屏障(实现锁机制相关);

屏障的作用是:禁止处理器把 final 变量重排序到构造函数之外;

3)对普通的变量,不管是在 final 变量之前或之后赋值,都有可能被重排序至后面,在把对象的引用赋值给引用变量该操作之后;

对 final 变量读操作的重排序规则

1)在一个线程中,初次读对象的引用操作,与初次读该对象的 final 变量操作,JMM禁止处理器重排序这两个操作(这个规则仅仅针对处理器);

2)编译器会在读 final 变量操作之前插入 LoadLoad 屏障;

如果 final 变量是引用类型

1)对引用类型的 final 变量写操作,前面指出的重排序规则对编译器、处理器增加如下约束:

在构造函数内对引用类型的 final 变量的写操作,与之后在构造函数外把包含该 final 引用类型变量的对象的引用赋值给引用变量操作,这两个操作之间不能重排序;

标签: #java中的关键字