Java面试:a+=a-=aa原理解析

ops/2025/2/13 14:24:58/

Java面试:a+=a-=a*a原理解析

a+=a-=a*a属于Java基础中比较难以理解的,面试中也经常会遇到这个问题,本篇博客对此问题进行分享总结。

1.问题代码
	public static void main(String[] args) {int a = 2;a+=a-=a*a;System.out.println("a="+a);}

我第一次遇见这个问题的时候,很不巧的算错了结果还和运行结果一致。在后面梳理思路时发现其中问题,反编译class文件才明白其中原理,感觉是个很有意思的问题。下面给出运行结果
运行结果
到这很多同学开始疑惑了吧,结果为什么不是-4。接下来看看JVM如何运行这段代码的。

 public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATICCode:stack=4, locals=2, args_size=10: iconst_21: istore_12: iload_13: iload_14: iload_15: iload_16: imul7: isub8: dup9: istore_110: iadd11: istore_112: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;15: new           #3                  // class java/lang/StringBuilder18: dup19: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V22: ldc           #5                  // String a=24: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;27: iload_128: invokevirtual #7                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;31: invokevirtual #8                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;34: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V37: returnLineNumberTable:line 5: 0line 6: 2line 7: 12line 8: 37
}

这是用javap -verbose反编译的代码。
先看指令号为2、3、4、5完成的事情,这四行指令完成了将运算需要的数据加载到操作数栈中。在这里插入图片描述
指令号6(imul)将栈顶两int型数值相乘并将结果压入栈顶
在这里插入图片描述
指令号7(isub)将栈顶两int型数值相减并将结果压入栈顶
在这里插入图片描述
指令号8(dup)复制栈顶数值并将复制值压入栈顶
在这里插入图片描述
指令号9(istore_1) 将栈顶int型数值存入局部变量表第二个位置,第一个赋值操作出现了。
在这里插入图片描述
关键点出现了,指令号10(iadd)将栈顶两个int值相加操作数栈现在只有-2和2,明显a+=a-=a*a中a+=的a并没有重新去栈中取值,准确的说四个a的值在计算开始时已经全部取出。所以最后相加的时候,用的是刚开始时定义的a的值。
在这里插入图片描述


http://www.ppmy.cn/ops/158060.html

相关文章

从0到1构建 Kubernetes中间件运维平台:标准化、可视化与全栈运维的最佳实践|得物技术

一、项目背景 传统运维的痛点与挑战 在传统的中间件运维过程中&#xff0c;存在以下几个突出问题&#xff1a; 管理分散&#xff1a;不同中间件&#xff08; Kafka和Elasticsearch&#xff09;都有独立的管理台&#xff0c;运维逻辑分散&#xff0c;难以形成统一规范。成本高…

【Linux系统】—— 简易进度条的实现

【Linux系统】—— 简易进度条的实现 1 回车和换行2 缓冲区3 进度条的准备代码4 第一版进度条5 第二版进度条 1 回车和换行 先问大家一个问题&#xff1a;回车换行是什么&#xff0c;或者说回车和换行是同一个概念吗&#xff1f;   可能大家对回车换行有一定的误解&#xff0…

【学习笔记】计算机网络(三)

第3章 数据链路层 文章目录 第3章 数据链路层3.1数据链路层的几个共同问题3.1.1 数据链路和帧3.1.2 三个基本功能3.1.3 其他功能 - 滑动窗口机制 3.2 点对点协议PPP(Point-to-Point Protocol)3.2.1 PPP 协议的特点3.2.2 PPP协议的帧格式3.2.3 PPP 协议的工作状态 3.3 使用广播信…

【网络安全.渗透测试】Cobalt strike(CS)工具使用说明

目录 前言 一、工具显著优势 二、安装 Java 运行环境 三、实验环境搭建要点 四、核心操作流程详解 (一)环境准备与连接步骤 (二)主机上线与深度渗透流程 五、其他实用功能应用指南 (一)office 宏 payload 应用 (二)Https Payload 应用 (三)信息收集策略 …

使用EVE-NG-锐捷实现ACL访问控制

一、ACL基础知识 ACL&#xff08;Access Control List&#xff0c;访问控制列表&#xff09;是网络安全和访问控制领域的重要概念 1.定义与基本原理 ACL是网络设备&#xff08;如路由器、交换机等&#xff09;中用于控制网络流量和访问权限的机制&#xff0c;由一系列规则组…

【C++】解锁<list>的正确姿势

> &#x1f343; 本系列为初阶C的内容&#xff0c;如果感兴趣&#xff0c;欢迎订阅&#x1f6a9; > &#x1f38a;个人主页:[小编的个人主页])小编的个人主页 > &#x1f380; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 > ✌️ &#x1f91e; &#x1…

rpx和px混用方案

&#xff08;1&#xff09;创建一个全局的样式配置文件&#xff1a; // styles/variables.scss :root {// 基础字体大小--font-size-xs: 12px;--font-size-sm: 14px;--font-size-md: 16px;--font-size-lg: 18px;// 响应式间距--spacing-xs: 5px;--spacing-sm: 10px;--spacing-…

基于Ollama安装deepseek-r1模型搭建本地知识库

大模型 安装Ollama使用win系统安装使用sh脚本安装使用docker安装 下载大模型搭建本地知识库安装Dify对比参数模型 本实验主要使用win系统安装ollama部署deepseek-r1&#xff08;1.5b、7b、8b、14b、32b等参数&#xff09;并搭建本地知识库&#xff08;个人学习研究为主&#xf…