博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用jvm指令分析String 常量池
阅读量:6213 次
发布时间:2019-06-21

本文共 3245 字,大约阅读时间需要 10 分钟。

其他博友的不同理解方式:   

我们先来看一个类

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 javaPTestCompiled 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."
":()V 4: returnpublic 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."
":(Ljava/lang/String;)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."
":(Ljava/lang/String;)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/String;)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."
":(Ljava/lang/String;)V 22: astore 5

执行过程中堆栈的变化 

所谓的常量池就是在内存中的一个数组,这个数组中记录的都是直面量,并且在数组中,不会出现相同的直面量。

 

 

转载于:https://www.cnblogs.com/fjsnail/p/3473611.html

你可能感兴趣的文章
20155222 2016-2017-2 《Java程序设计》实验一
查看>>
时间戳 时间 相互转换
查看>>
BZOJ2208:[JSOI2010]连通数——题解
查看>>
asp.net代码中尖括号和百分号的含义 <转载>
查看>>
2-sat
查看>>
Jquery DataTable控制显示列,导出EXCEL
查看>>
实验证明:Objective-C++ 完美支持 ARC
查看>>
第八章 Libgdx输入处理(10)触摸屏
查看>>
【mysql】新方法修改数据库密码以及解决--ERROR 1045 (28000)的问题
查看>>
C# ListView控件使用简介
查看>>
当你的才华还不足以支撑起你的野心时,你就该静下心来学习
查看>>
包加载失败的解决办法
查看>>
100款编程在线工具|果断收藏!
查看>>
C语言简单实现链栈基本几个功能
查看>>
《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(15)--- 监视器对象...
查看>>
开通技术博客
查看>>
使用SecureCRT在Linux与Windows之间传输文件
查看>>
git获取远程仓库的方式
查看>>
atomic integer operations P176
查看>>
springboot之HelloWorld
查看>>