其他博友的不同理解方式:  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. 使用SpringData出现java.lang.AbstractMethodError

    最近学习一下SpringData,在添加SpringData支持的时候,出现了这样的问题: SpringData需要的jar有:spring-data-jpa.jar  spring-data-com ...

  2. 【UVA】1595 Symmetry(模拟)

    题目 题目     分析 理清思路,上模拟.     代码 #include <bits/stdc++.h> using namespace std; const int maxn=100 ...

  3. 【BZOJ】1008: [HNOI2008]越狱(组合数学)

    题目 题目描述 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱 输入输出格式 ...

  4. java实现时钟方法汇总

    import java.awt.Dimension; import java.text.SimpleDateFormat; import java.util.Calendar; import java ...

  5. PowerMock单元测试

    在Java程序的单元测试中常用的mock工具有Mockito和EasyMock.但是这两种mock工具都无法实现对静态.final.私有方法或类的mock.因此有了功能强大的PowerMock工具.P ...

  6. Nginx加状态监控

    安装Nginx时加上        –with-http_stub_status_module 在nginx.conf server location /nginx_status { stub_sta ...

  7. python学习笔记(十二):发送邮件

    我们在开发程序的时候,有时候需要开发一些自动化的任务,执行完之后,将结果自动的发送一份邮件,python发送邮件使用smtplib模块,是一个标准包,直接import导入使用即可,代码如下: impo ...

  8. leetcode513

    /** * Definition for a binary tree node. * public class TreeNode { * public int val; * public TreeNo ...

  9. WebSocket实践——Java实现WebSocket的两种方式

    什么是 WebSocket? 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信 ...

  10. 留存- angularjs 弹出框 $modal

    $modal只有一个方法:open,该方法的属性有: templateUrl:模态窗口的地址 template:用于显示html标签 scope:一个作用域为模态的内容使用(事实上,$modal会创建 ...