其他博友的不同理解方式:  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 常量池的更多相关文章

  1. java基础进阶一:String源码和String常量池

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/8046564.html 邮箱:moyi@moyib ...

  2. Java String 常量池理解

    String:字符串常量池 作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三个问题,去理解字符串常量池: 字 ...

  3. Java的Integer常量池和String常量池

    1.Integer的常量池 看下面一段代码: package cn.qlq.test; public class ArrayTest { public static void main(String[ ...

  4. java基础知识回顾之---java String final类 容易混淆的java String常量池内存分析

    /** *   栈(Stack) :存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放  在常量池中). 堆(heap):存 ...

  5. jvm堆、栈、String常量池

    原文地址:http://blog.csdn.net/tophawk/article/details/78704074 程序计数器:它的生命周期与线程相同,线程私有.较小的内存区域,用以完成分支.循环. ...

  6. 深入理解JVM内存分配和常量池

    一.虚拟机的构成 虚拟结主要由运行时数据区.执行引擎.类加载器三者构成: 而我们所说的JVM内存模型指的就是运行时数据区,下面具体分析一下运行时数据区: 二.运行时数据区组成和各个区域的作用 我们看到 ...

  7. 字符串String: 常量池

    2.1          String类 String是不可变类, 即一旦一个String对象被创建, 包含在这个对象中的字符序列是不可改变的, 直至该对象被销毁. String类是final类,不能 ...

  8. 资深架构师教你String 常量池、 String.itern()

    什么是常量 用final修饰的成员变量表示常量,值一旦给定就无法改变! final修饰的变量有三种:静态变量.实例变量和局部变量,分别表示三种类型的常量. Class文件中的常量池 在Class文件结 ...

  9. 0024 Java学习笔记-面向对象-包装类、对象的比较、String常量池问题

    包装类 基本类型-->包装类 byte-->Byte short-->Short int-->Integer long-->Long char-->Characte ...

随机推荐

  1. 使用Ajax异步上传文件

    之前上传文件都是用表单form设置post请求和enctype类型: <form id="upload_form"action="" method=&qu ...

  2. Web api help page error CS0012: Type "System.Collections.Generic.Dictionary'2错误

    1.在asp.net Boilerplate项目中,Abp.0.12.0.2,.net framework4.5.2.下载后添加了webApi的helpPage功能,调试出现错误. dubug : a ...

  3. Window性能监视器

    Microsoft Web Application Stress Tool 微软的分布式网站性能压力测试工具 Window性能监视器 1.监测IIS连接数量 从“开始”菜单上选择“运行”. 在“打开” ...

  4. Integer-->String String-->Integer

    参考:http://blog.csdn.net/wangjolly/article/details/18354457 crane: String str="123";int a=0 ...

  5. ceph---luminous版的安装

    前言 ceph luminous版本新增加了很多有意思的功能,这个也是一个长期支持版本,所以这些新功能的特性还是很值得期待的,从底层的存储改造,消息方式的改变,以及一些之前未实现的功能的完成,都让ce ...

  6. Storm开发——环境配置部署

    配置开发环境:http://storm.apache.org/releases/current/Setting-up-development-environment.html 开发环境定义: Stor ...

  7. Docker垃圾回收机制

    由Docker垃圾回收机制引发的一场血案 AlstonWilliams 关注 2017.04.01 19:00* 字数 1398 阅读 253评论 0喜欢 0 今天早晨,在我还没睡醒的时候,我们团队中 ...

  8. leetcode two pointer

    16. 3Sum Closest 这道题让我们求最接近给定值的三数之和,是在之前那道3Sum 三数之和的基础上又增加了些许难度,那么这道题让我们返回这个最接近于给定值的值,即我们要保证当前三数和跟给定 ...

  9. TortoiseSVN/Git覆盖图标失效的解决方案

    之前在电脑上安装了TortoiseGit和TortoiseSVN这两种版本控制,使用一段时间之后发现,这两种版本控制的覆盖图标都无法显示,起初以为是git和svn使用的图标的不一样,有冲突,导致这两种 ...

  10. 查看DNS服务器

    电脑右键查看本地连接 查看状态 然后看DNS