final 原理

1. 设置 final 变量的原理

理解了 volatile 原理,再对比 final 的实现就比较简单了

public class TestFinal {
    final int a = 20;
}

字节码

0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: bipush 20
7: putfield #2 // Field a:I
<-- 写屏障
10: return


        发现 final 变量的赋值也会通过 putfield 指令来完成,同样在这条指令之后也会加入写屏障,保证在其它线程读到它的值时不会出现为 0 的情况(因为int a = 20对应的字节码有多步,第一步分配空间,此时初始值为0,赋值是第二步,之间可能发生线程上下文切换,产生对共享变量a的指令交错,导致另一个线程读取到0)。

 2. 获取 final 变量的原理

        获取 final 变量时,根据字节码指令, 数字较小,复制到自己的栈中读取,较大,超出短整型,在常量池读取。是直接把final变量的值,复制到该(方法)线程的操作数栈中,即复制到其他类中,没有共享的操作。

 

        不加final,在堆中读取,效率较低。

 

 

       

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值