从源码里的一个注释,我追溯到了12年前,有点意思

2024-02-23 07:20

本文主要是介绍从源码里的一个注释,我追溯到了12年前,有点意思,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

那天我正在用键盘疯狂的输出:

突然微信弹出一个消息,是一个读者发给我的。

我点开一看:

啊,这熟悉的味道,一看就是 HashMap,八股文梦开始的地方啊。

但是他问出的问题,似乎又不是一个属于 HashMap 的八股文:

为什么这里要把 table 变量赋值给 tab 呢?

table 大家都知道,是 HashMap 的一个成员变量,往 map 里面放的数据就存储在这个 table 里面的:

在 putVal 方法里面,先把 table 赋值给了 tab 这个局部变量,后续在方法里面都是操作的这个局部变量了。

其实,不只是 putVal 方法,在 HashMap 的源码里面,“tab= table” 这样的写发多达 14 个,比如 getNode 里面也是这样的用法:

我们先思考一下,如果不用 tab 这个局部变量,直接操作 table,会不会有问题?

从代码逻辑和功能上来看,是不会有任何毛病的。

如果是其他人这样写,我会觉得可能是他的编程习惯,没啥深意,反正又不是不能用。

但是这玩意可是 Doug Lea 写的,隐约间觉得必然是有深意在里面的。

所以为什么要这样写呢?

巧了,我觉得我刚好知道答案是什么。

因为我在其他地方也看到过这种把成员变量赋值给局部变量的写法,而且在注释里面,备注了自己为什么这么写。

而这个地方,就是 Java 的 String 类:

比如 String 类的 trim 方法,在这个方法里面就把 String 的 value 赋给了 val 这个局部变量。

然后旁边给了一个非常简短的注释:

avoid getfield opcode

本文的故事,就从一行注释开始,一路追溯到 2010 年,我终于抽丝剥茧找到了问题的答案。

一行注释,就是说要避免使用 getfield 字节码。

虽然我不懂是啥意思,但是至少我拿到了几个关键词,算是找到了一个“线头”,接下来的事情就很简单了,顺着这个线头往下缕就完事了。

而且直觉上告诉我这又是一个属于字节码层面的极端的优化,缕到最后一定是一个骚操作。

那么我就先给你说结论了:这个代码确实是 Doug Lea 写的,在当年确实是一种优化手段,但是时代变了,放到现在,确实没有卵用。

答案藏在字节码

既然这里提到了字节码的操作,那么接下来的思路就是对比一下这两种不同写法分别的字节码是长啥样的不就清楚了吗?

比如我先来一段这样的测试代码:

public class MainTest {private final char[] CHARS = new char[5];public void test() {System.out.println(CHARS[0]);System.out.println(CHARS[1]);System.out.println(CHARS[2]);}public static void main(String[] args) {MainTest mainTest = new MainTest();mainTest.test();}
}

上面代码中的 test 方法,编译成字节码之后,是这样的:

可以看到,三次输出,对应着三次这样的字节码:

在网上随便找个 JVM 字节码指令表,就可以知道这几个字节码分别在干啥事儿:

  • getstatic:获取指定类的静态域, 并将其压入栈顶
  • aload_0:将第一个引用类型本地变量推送至栈顶
  • getfield:获取指定类的实例域, 并将其值压入栈顶
  • iconst_0:将int型0推送至栈顶
  • caload:将char型数组指定索引的值推送至栈顶
  • invokevirtual:调用实例方法

如果,我把测试程序按照前面提到的写法修改一下,并重新生成字节码文件,就是这样的:

可以

这篇关于从源码里的一个注释,我追溯到了12年前,有点意思的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/737901

相关文章

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

vscode中文乱码问题,注释,终端,调试乱码一劳永逸版

忘记咋回事突然出现了乱码问题,很多方法都试了,注释乱码解决了,终端又乱码,调试窗口也乱码,最后经过本人不懈努力,终于全部解决了,现在分享给大家我的方法。 乱码的原因是各个地方用的编码格式不统一,所以把他们设成统一的utf8. 1.电脑的编码格式 开始-设置-时间和语言-语言和区域 管理语言设置-更改系统区域设置-勾选Bata版:使用utf8-确定-然后按指示重启 2.vscode

Maven创建项目中的groupId, artifactId, 和 version的意思

文章目录 groupIdartifactIdversionname groupId 定义:groupId 是 Maven 项目坐标的第一个部分,它通常表示项目的组织或公司的域名反转写法。例如,如果你为公司 example.com 开发软件,groupId 可能是 com.example。作用:groupId 被用来组织和分组相关的 Maven artifacts,这样可以避免

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

kubelet组件的启动流程源码分析

概述 摘要: 本文将总结kubelet的作用以及原理,在有一定基础认识的前提下,通过阅读kubelet源码,对kubelet组件的启动流程进行分析。 正文 kubelet的作用 这里对kubelet的作用做一个简单总结。 节点管理 节点的注册 节点状态更新 容器管理(pod生命周期管理) 监听apiserver的容器事件 容器的创建、删除(CRI) 容器的网络的创建与删除

STL经典案例(四)——实验室预约综合管理系统(项目涉及知识点很全面,内容有点多,耐心看完会有收获的!)

项目干货满满,内容有点过多,看起来可能会有点卡。系统提示读完超过俩小时,建议分多篇发布,我觉得分篇就不完整了,失去了这个项目的灵魂 一、需求分析 高校实验室预约管理系统包括三种不同身份:管理员、实验室教师、学生 管理员:给学生和实验室教师创建账号并分发 实验室教师:审核学生的预约申请 学生:申请使用实验室 高校实验室包括:超景深实验室(可容纳10人)、大数据实验室(可容纳20人)、物联网实验