其他博友的不同理解方式:  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. Android 应用获取Jenkins编译的版本号

    Android很多应用的版本号最后都带了编译的版本号.比如说V1.0.0.125,后边的125就通常使用每次编译之后build history的号码,它是逐次增加,这样就可以区分每个细分的编译版本号, ...

  2. Android:ScrollView和SwipeRefreshLayout高度测量

    今天组里的同事要做一个奇葩的效果,要求在ScrollView里嵌套一个RefreshLayout.类似代码如下: <?xml version="1.0" encoding=& ...

  3. php xss漏洞修复用手段和用到的一些函数

    php xss漏洞修复用到的一些函数 $text = '<p>"Test paragraph".</p><!-- Comment --> < ...

  4. php header 302重定向失效问题

    E:\html\pim\php_weili_activities\application\controllers\user.php public function login() { if ($thi ...

  5. BIO模型

    基本模型 代码: 客户端 package bhz.bio; import java.io.BufferedReader; import java.io.IOException; import java ...

  6. sql server 2005 修改动态端口,连接字符串为:需要改成:IP地址+逗号+端口号才行

    1.sql server 2005 安装完毕后,默认是动态段,需要用sql brower 查询端口号:修改给固定端口后,格式为:IP地址+逗号+端口号. 2.sql 2000 的格式为:格式为:IP地 ...

  7. Embarcadero RAD Studio 2016 Product Approach and Roadmap

    delphi  2016 路线图 http://community.embarcadero.com/article/news/16211-embarcadero-rad-studio-2016-pro ...

  8. 跟我学算法-tensorflow 实现logistics 回归

    tensorflow每个变量封装了一个程序,需要通过sess.run 进行调用 接下来我们使用一下使用mnist数据,这是一个手写图像的数据,训练集是55000*28*28, 测试集10000* 28 ...

  9. 关于LOH(Large Object Heap)及内存泄漏

    关于LOH(Large Object Heap)的. .NET CLR中对于大于85000字节的内存既不像引用类型那样分配到普通堆上,也不像值类型那样分配到栈上,而是分配到了一个特殊的称为LOH的内部 ...

  10. 详解C++右值引用

    C++0x标准出来很长时间了,引入了很多牛逼的特性[1].其中一个便是右值引用,Thomas Becker的文章[2]很全面的介绍了这个特性,读后有如醍醐灌顶,翻译在此以便深入理解. 目录 概述 mo ...