用jvm指令分析String 常量池
其他博友的不同理解方式: http://hi.baidu.com/boywell/item/d5ee5b0cc0af55c875cd3cfd
我们先来看一个类
public class javaPTest { /**常量池
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String i1 = "hello";
String i2="world";
String i3="helloworld";
String i4="hello"+"world";
String i5=new String("helloworld");
String i6=new String("helloworld"); System.out.println("helloworld"); System.out.println(i5==i6);
System.out.println(i3==i4);
} }
result: helloworld false true
why?我们可以通过javap -c javaPTest (前提是:先用javac编译通过) 来看该类的反编译结果
注意: ldc #2 是将常量池中下标为2的常量加载到栈中
astore_1 将栈顶元素存到到当前fame局部变量数组下标为1的变量中,栈顶元素出栈
invokespecial 调用超类构造方法、实例初始化方法、私有方法
aload:当前frame的局部变量数组中下标为index的引用型局部变量进栈
ldc :将int、float或String型常量值从常量池中推送至栈顶
astore i: 将栈顶数值(objectref)存入当前frame的局部变量数组中指定下标(index)处的变量中,栈顶数值出栈。
new :创建一个对象,并且其引用进栈
dup :复制栈顶数值,并且复制值进栈 F:\JAVA\javaIDE\study11.29\src\com\study\main>javap -c javaPTest
Compiled from "javaPTest.java"
public class com.study.main.javaPTest extends java.lang.Object{
public com.study.main.javaPTest();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return public static void main(java.lang.String[]);
Code:
0: ldc #2; //String hello //将string类型常量值(hello)从常量池推送至栈顶
2: astore_1 //将
3: ldc #3; //String world
5: astore_2
6: ldc #4; //String helloworld
8: astore_3
9: ldc #4; //String helloworld
11: astore 4
13: new #5; //class java/lang/String //new了一个String对象,并将其引用进栈,
16: dup
17: ldc #4; //String helloworld
19: invokespecial #6; //Method java/lang/String."<init>":(Ljava/lang/Strin
g;)V
22: astore 5
24: new #5; //class java/lang/String
27: dup
28: ldc #4; //String helloworld
30: invokespecial #6; //Method java/lang/String."<init>":(Ljava/lang/Strin
g;)V
33: astore 6
35: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream;
38: ldc #4; //String helloworld
40: invokevirtual #8; //Method java/io/PrintStream.println:(Ljava/lang/Str
ing;)V
43: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream;
46: aload 5 //将常量数组中下边为5和6的变量加载到栈中(其实两个都存放#4 17行和28行分别表示在数组的4,5下标中,存放#4)
48: aload 6
50: if_acmpne 57 //比较 如果不相等就跳转
53: iconst_1
54: goto 58
57: iconst_0
58: invokevirtual #9; //Method java/io/PrintStream.println:(Z)V
61: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream;
64: aload_3 //将常量数组中下边为3和4的变量加载到栈中(其实两个都存放#4 8行和11行分别表示在数组的3,4下标中,存放#4)
65: aload 4
67: if_acmpne 74
70: iconst_1
71: goto 75
74: iconst_0
75: invokevirtual #9; //Method java/io/PrintStream.println:(Z)V
78: return }
我们重点看看String i5=new String("helloworld");对应的反编译代码
13: new #5; //class java/lang/String //new了一个String对象,并将其引用进栈,
16: dup
17: ldc #4; //String helloworld
19: invokespecial #6; //Method java/lang/String."<init>":(Ljava/lang/Strin
g;)V
22: astore 5
执行过程中堆栈的变化
用jvm指令分析String 常量池的更多相关文章
- java基础进阶一:String源码和String常量池
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/8046564.html 邮箱:moyi@moyib ...
- Java String 常量池理解
String:字符串常量池 作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三个问题,去理解字符串常量池: 字 ...
- Java的Integer常量池和String常量池
1.Integer的常量池 看下面一段代码: package cn.qlq.test; public class ArrayTest { public static void main(String[ ...
- java基础知识回顾之---java String final类 容易混淆的java String常量池内存分析
/** * 栈(Stack) :存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放 在常量池中). 堆(heap):存 ...
- jvm堆、栈、String常量池
原文地址:http://blog.csdn.net/tophawk/article/details/78704074 程序计数器:它的生命周期与线程相同,线程私有.较小的内存区域,用以完成分支.循环. ...
- 深入理解JVM内存分配和常量池
一.虚拟机的构成 虚拟结主要由运行时数据区.执行引擎.类加载器三者构成: 而我们所说的JVM内存模型指的就是运行时数据区,下面具体分析一下运行时数据区: 二.运行时数据区组成和各个区域的作用 我们看到 ...
- 字符串String: 常量池
2.1 String类 String是不可变类, 即一旦一个String对象被创建, 包含在这个对象中的字符序列是不可改变的, 直至该对象被销毁. String类是final类,不能 ...
- 资深架构师教你String 常量池、 String.itern()
什么是常量 用final修饰的成员变量表示常量,值一旦给定就无法改变! final修饰的变量有三种:静态变量.实例变量和局部变量,分别表示三种类型的常量. Class文件中的常量池 在Class文件结 ...
- 0024 Java学习笔记-面向对象-包装类、对象的比较、String常量池问题
包装类 基本类型-->包装类 byte-->Byte short-->Short int-->Integer long-->Long char-->Characte ...
随机推荐
- 第十二章 Ganglia监控Hadoop及Hbase集群性能(安装配置)
1 Ganglia简介 Ganglia 是 UC Berkeley 发起的一个开源监视项目,设计用于测量数以千计的节点.每台计算机都运行一个收集和发送度量数据(如处理器速度.内存使用量等)的名为 gm ...
- Go - coding之前的准备
Go tool 的使用 Go的tool要求我们对于code有一定的结构化组织和管理,下面我们就来一介绍他们: --GoPath environment variable: 顾名思义,环境变量,指定了 ...
- python学习 (三十) python的函数
1: 函数参数默认值 def method1(p1 = , p2 = ): // 函数有两个参数,并且都有默认值 return p1 + p2 print(method1()) print(meth ...
- java 字符串排序
http://bbs.csdn.net/topics/280032929 大可不需要那样复杂了!(一)如果要排序的为字符串,如:String sortStr = "ACDFE"; ...
- php if判断
php if判断 例子如下: True是否等于False 变量haq是不是老婆呢? <?php $ts=true; $f=false; if (isset($ts)&&isset ...
- 【转】Android编码规范建议18条
转自:http://www.chinaz.com/design/2015/0908/443732.shtml Android编码规范建议18条 适合手机app设计师和android 工程师阅读. 1. ...
- leetcode hashmap
187. Repeated DNA Sequences 求重复的DNA序列 public List<String> findRepeatedDnaSequences(String s) { ...
- nginx作用
图解nginx作用:
- DataMatrix二维条码源码分析检测识别图像位置
发布时间:2014-10-31 DataMatrix的代码结构和QR码基本相同: 其中Detector的功能还是从原始图像中找出符号码的部分,并且进行透视转换纠正扭曲. 其解码流程与QR码差不多,关键 ...
- Tomcat ( 单机多 Tomcat 并存 )
简介: Tomcat 扩展( 一台服务器运行多个 tomcat ) 一.安装 JDK .Tomcat shell > rpm -ivh jdk-8u25-linux-x64.rpm # 安装 j ...