通过Java字节码发现有趣的内幕之String篇(上)(转)
2016-04-03 21:54
501 查看
原文出处: jaffa
很多时候我们在编写Java代码时,判断和猜测代码问题时主要是通过运行结果来得到答案,本博文主要是想通过Java字节码的方式来进一步求证我们已知的东西。这里没有对Java字节码知识进行介绍,如果想了解更多的Java字节码或对其感兴趣的朋友可以先阅读字节码基础:JVM字节码初探。
String字面量可以通过’==’判断两个字符串是否相同,是因为大家都知道’==’是用来判断两个对象的值引用地址是否一致,两个值一样的字符串字面量定义是否指向同一个值内存地址呢?答案是肯定的。
代码中声明了str1和str2的字面量值都为strVal_1,并且打印出str1==str2为true,说明两个str1和str2变量同时指向同一个字符串常量值的内存地址,下面通过Java字节码来验证这个结果。
在命令行我们通过javap工具来查看一个class文件的字节码。
在Constant pool列表中看到#16为一个String类型并值指向#17,而#17是一个utf8字符集编码值为strVal_1,所以#16和#17最终表达就是在常量池中有个String类型值为strVal_1的常量数据。
那接下来需要确认str1和str2两个变量值是否都是指向#16呢?
从上面字节码执行来看,str1和str2都是被赋于同一个常量值,由此可以得出两个变更指向同一个内存地址。
通过同样的方式,我们来看一下如果是非字面量的情况会是怎么样的,Java代码如下:
上面代码输出结果为false,通过javap查看发现str2变量的字节码指令发生了变化,如下现两截图:
这时str2变量是创建一个新的内存地址,而非直接指向#16常量内存地址,所以str1==str2的结果为false。同时可以看到通过new String()带来看更多的字节码指令操作,运行上花费了更多的系统资源。
通过Java字节码发现有趣的内幕之String篇(中)
通过Java字节码发现有趣的内幕之初始化篇(下)
http://www.importnew.com/18785.html
很多时候我们在编写Java代码时,判断和猜测代码问题时主要是通过运行结果来得到答案,本博文主要是想通过Java字节码的方式来进一步求证我们已知的东西。这里没有对Java字节码知识进行介绍,如果想了解更多的Java字节码或对其感兴趣的朋友可以先阅读字节码基础:JVM字节码初探。
String字面量可以通过’==’判断两个字符串是否相同,是因为大家都知道’==’是用来判断两个对象的值引用地址是否一致,两个值一样的字符串字面量定义是否指向同一个值内存地址呢?答案是肯定的。
在命令行我们通过javap工具来查看一个class文件的字节码。
在Constant pool列表中看到#16为一个String类型并值指向#17,而#17是一个utf8字符集编码值为strVal_1,所以#16和#17最终表达就是在常量池中有个String类型值为strVal_1的常量数据。
那接下来需要确认str1和str2两个变量值是否都是指向#16呢?
通过同样的方式,我们来看一下如果是非字面量的情况会是怎么样的,Java代码如下:
本系列:
通过Java字节码发现有趣的内幕之String篇(上)通过Java字节码发现有趣的内幕之String篇(中)
通过Java字节码发现有趣的内幕之初始化篇(下)
http://www.importnew.com/18785.html
相关文章推荐
- jdk 1.7中HashMap的HashIterator实现细节小记
- Java命令学习系列(7):Javap(转)
- JAVA注解
- Java数据库篇
- 【JAVA】腾讯研发类在线笔试题之蛇形矩阵实现
- MYBATIS+SPRING 配置
- 排序算法之希尔排序(Java)
- 希尔排序及希尔排序java代码
- 排序算法之冒泡排序(Java)
- 排序算法之简单选择排序(Java)
- 排序算法之堆排序(Java)
- 20160402javaweb 开发模式
- JAVA大数类 BigInteger和BigDecimal用法
- 20145221 《Java程序设计》第五周学习总结
- Java重写方法与初始化的隐患(转)
- Spring(四)注解配置Ioc
- Spring(三)AOP面向切面编程
- (第7讲)java基本数据类型转换
- Spring(二)scope、集合注入、自动装配、生命周期
- Java泛型总结