其他博友的不同理解方式:  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. 安装windows 2003 server

    最近去给客户安装windows 2003 server,想想也是技术,就写出来了,我这个实在虚拟机安装的,安装这个系统主要是为了安装limesurvey问卷系统 第一步:安装,选择Enter 第二步: ...

  2. node制作代理服务器

    下面代码实现的功能是这样的: 首先创建一个HTTP服务器,当服务器接收到客户端的请求后,向"www.taobao.com"网站请求数据,当从该网站接受到的响应数据后,将响应数据发送 ...

  3. 【BZOJ】2938 [POI2000]病毒(AC自动机)

    题目 传送门:QWQ 传送到洛谷QWQ 分析 夏爷爷传送门 代码 #include <bits/stdc++.h> using namespace std; ; ][], fail[N*] ...

  4. JAVA访问控制变量、类变量、类方法

    1.私有:同类中 2.默认:同包中的类 3.保护:同包中的类  子类中(继承性) 4.公有:无范围 创建子类并覆盖方法时,必须考虑原来方法的访问控制: 作为通用的规则,覆盖方法是,新方法的访问控制不能 ...

  5. JAVA中的IO流介绍(2)

    一.流的概念 流(stream)的概念源于UNIX中管道(pipe)的概念.在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备.外部文件等. 一个流,必有源端和目的端, ...

  6. js中的web加密

    js中的web加密 window.crypto.subtle只会在安全模式下有用,也就是https环境下 创建摘要(硬解) var i = new TextEncoder('utf-8').encod ...

  7. cisco 三层交换机通信

    前言 之前学了交换机和路由器今次学三层交换机的通信. 正文 准备:cisco模拟器 一台三层交换机 两台PC 配置命令如下 enable config t vlan 10 exit vlan 20 e ...

  8. 指向“**js/shop.js”的 <script> 加载失败

    指向“”的 <script> 加载失败 找了半天没找到原因 原来是meta里面的 csp Content-Security-Policy <meta http-equiv=" ...

  9. JS控制文字只显示两行,超出部分显示省略号

    由于使用css控制文字只显示多行,超出部分显示省略号,存在一定的兼容性问题,所以总结了一下网上一些大咖使用js实现控制行数的解决方案. 第一步:依次引入jquery.js+jquery.ellipsi ...

  10. 关于服务器raid的一个记录

    今天下午,在装操作系统的时候,特意的测试了下raid1的性能. 1. 开启操作系统 直接正常开启操作系统,操作系统的硬盘做的是raid1,从而数据写俩份,从而在损坏一张盘之后,另外一张盘并不会收到影响 ...