LinkedList源码中为何大量出现final

2022/2/21 11:35:49

本文主要是介绍LinkedList源码中为何大量出现final,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

源码中出现final的地方

  • 所有的link有关的方法(增删操作)add remove
  • 需要保存中间变量的节点(prev和next指针需要修改的节点)
  • 像clear get这种不涉及“更改指针指向”的方法不需要对中间变量定义final

linkFirst
unlink

final的作用

final关键字的作用

LinkedList中Node是一个对象,因此适用于第二条引用数据类型,举个例子:

有无final修饰的浅拷贝

People p1 = new People(18,"张三");
People p2 = p1;
  1. 当:p1 = null;或者p1 = new People(20,“李四”);
    实际上是栈中的p1存储的地址改变,但堆空间中之前 new People(18,“张三”);的对象仍然存在。因此p2不受影响

  2. 当:p1.setAge(21); 此时操作的是堆空间中的唯一对象,p2会受到影响

在源码中:

    final E element = x.item;
    final Node<E> next = x.next;
    final Node<E> prev = x.prev;

使得element next prev三个属性栈空间保存的地址不可再被重定向,但可以修改值,例如:next.prev = prev和prev.next=next 可以对栈所指向的堆成员变量进行修改

使用final初始化的优点

参考链接:

https://www.cnblogs.com/noteless/p/10416678.html
https://www.cnblogs.com/noteless/p/10410368.html
https://www.cnblogs.com/mianlaoshu/articles/3648403.html
https://www.cnblogs.com/maxiaopao/p/9212903.html
https://zhuanlan.zhihu.com/p/88775601
https://www.zhihu.com/question/21762917/answer/19239387
第四条链接中讲final的优点很详细
第五条讲到了重排序
第六条是JVM对方法中的final变量性能调优

安全性分析

  • LinkedList本身是不安全,但这并不影响,因为每次事务初始化的都不是同一个Node对象,如果多线程并发并同时add,那么即便是源码定义了final,也可能会出现错误,因此LinkedList在并发场景下需要自行同步
  • 但多线程并发对于方法中局部变量是不存在冲突的
  • 排除安全性的可能

性能分析

  • 在能够通过编译的前提下,无论局部变量声明时带不带final关键字修饰,对其访问的效率都一样。
  • 既然一样,那性能上没影响了。排除

规范

参考阿里巴巴的开发手册

不允许修改的局部变量声明为final更多的是一种规范,在实质作用上加与不加没有区别,但他就是个规范。排除任何可能对这个变量进行修改的可能性

本问题花了我14个小时,查阅了无数资料,问了无数的人,最后能总结出来的答案就是:规范
hhhh浪费了我一天的宝贵时间

总结

  • 方法内部初始化的final变量是局部变量
  • 没有多线程冲突问题
  • 局部静态基本数据变量定义final才有JVM优化,而引用类型则没有
  • final可以避免误操作可能带来的问题,因此对所有不会修改的局部变量都用final定义
  • LikedList仍然是线程不安全的,需要手动上锁


这篇关于LinkedList源码中为何大量出现final的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程