内容简介:欢迎加入我的知识星球(免费)欢迎关注公众账号了解更多信息“写程序的康德——思考、批判、理性”
Java 一直标榜自己是一个纯粹的面向对象语言, 自作聪明的为所有的值类型都提供相应的引用类型(不明白这两个概念,看之前的《一分钟理解传值和传引用》) 比如:int 类型对应的有 Integer,前者是一个值,后者是一个引用。 为了方便二者的转换又一个叫“自动拆装箱”的特性,把本来清晰的概念搞的乱七八糟。
一个优秀的语言应该语法简单,语义单一、清晰。
本文讨论它这些乌七八糟的概念(我也搞不懂),直接进入正题——通过阅读 JVM code 判断究竟发生了什么。
解读 class 文件
JVM 是一个栈式虚拟机,它提供的指令都是围绕着栈进行的。通过 javap -c <className> 查看一个 class 文件中的 JVM 指令。 如下代码,左边是 Java 代码右边是它的 JVM code。
看一下每条指令执行完后栈的变化: bipush 把数字 20 直接 push 到栈
invokestatic 调用一个静态方法在 堆 中构造一个对象,然后把对象的地址压入到栈
astore_1 把 Integer 对象的内存地址记录到一个内部变量中(JVM 在堆中维护了一张大的变量表,代表变量名和变量值的关系,可以想象成 HashMap。) 至此,Integer = 20 这句代码执行完毕。紧接着看,bipush 把 10 压入栈
asotre2 把变量 b 和栈中的 10 做关联(放到变量表中)
-
值变量所指向的内容(值)是放在栈中的,访问时直接操作栈
-
引用变量所指向的内容(对象)是放在堆中的,访问时先把变量载入到栈(通过aload_1 指令,例子中没有出现),再操作。
访问包装对象时发生了什么
Integer c = null; Integer d = 10; int e = c + d;
JVM code 为
-
包装对象的空指针问题
aconst_null 把一个空指针压入栈,astore_1 把栈顶的变量放入到变量表中,所以此时 a 是 null,所以会出现空指针错误。
-
包装对象的计算方法
8-16 是计算两数相加,aload_1 把变量表中的变量压入栈,invokervirtual 指令把对象转换成 int 重新入栈;12、13 行的逻辑也是如此。 16 行执行整数相加。 因为计算结果是 int 类型,所以最后通过 isotre_3 放到变量表。
自己分析
如果代码的最后一行写作 Integer e = c + d; ,JVM code 会变成
自己动手分析一下看看吧。
Java 的包装数据类型非常蹩脚,这是它为了追求“表面的面向对象”而付出的代价。 装逼之势如雷霆万钧 ,可怕。
欢迎加入我的知识星球(免费)
欢迎关注公众账号了解更多信息“写程序的康德——思考、批判、理性”
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 理解 TypeScript 类型拓宽
- 理解 TypeScript 类型收窄
- [译]理解 iOS 异常类型
- 理解JavaScript变量和类型
- 理解 MySQL 中的数字类型
- 反编译理解java枚举类型
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
51单片机应用从零开始
杨欣、王玉凤、刘湘黔 / 清华大学 / 2008-1 / 39.80元
《51单片机应用与实践丛书•51单片机应用从零开始》在分析初学者认知规律的基础上,结合国内重点大学一线教师的教学经验以及借鉴国外经典教材的写作手法,对51单片机的应用基础知识进行系统而翔实的介绍。读者学习每一章之后,"实例点拨"环节除了可以巩固所学的内容外,还开辟了单片机应用的视野;再加上"器件介绍"环节,又充实了对单片机从基础到应用所需要的知识。8051单片机不仅是国内用得最多的单片机之一,同时......一起来看看 《51单片机应用从零开始》 这本书的介绍吧!
JS 压缩/解压工具
在线压缩/解压 JS 代码
SHA 加密
SHA 加密工具