A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 观决 中级黑马   /  2014-6-4 15:14  /  1627 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 观决 于 2014-6-4 18:16 编辑

最近看到下面这样一段话  我晓得String a="abc" 是现在常量池中看有没有 有就直接把对象引用复制给a 没有创建一个在复制给a   
我不晓得他下面那个红色字体的 先在heap中创建 然后移到常量池中(不是直接在常量池中创建)  这是正确的吗(或者有哪本书中有这样写)?  有哪位晓得这个的过程的 麻烦说一下

当执行String a=“abc”;时,JAVA虚拟机会在栈中创建三个char型的值‘a’、‘b’和‘c’,然后在堆中创建一个String对象,它的值(value)是刚才在栈中创建的三个char型值组成的数组{‘a’,‘b’,‘c’},最后这个新创建的String对象会被添加到字符串池中。

2 个回复

倒序浏览
本帖最后由 观决 于 2014-6-4 18:20 编辑

常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据
String对象,一个是通过""双引号创建的,一个是通过new创建的.只不过他们创建的时期不同,一个是编译期,一个是运行期!  我觉得这样才对 这样上面那句
先在heap中创建 然后添加到字符串池中就不对了   
应该就是在编译时 发现""这样创建的 就看字符串常量池中有没有  有就将对象引用复制给a   不会再heap里面new创建的才是heap里

回复 使用道具 举报
本帖最后由 观决 于 2014-6-4 21:20 编辑

好吧 虽然问题被我结束了  我还是吧自己现在的理解说下   刚才看到很多 貌似懂了一些  
String a="haha"     属于字符串的常量池  这个是在编译期就存在的  被写入了class文件中
然后class被加载到   jvm  中时    jvm在Method Area区域给他开辟一个空间   用于常量池
然后  jvm底层是这样的  Method Area 属于堆  只不过GC一般不处理它   所以在jvm运行起来时 不会有上面的那一步先在堆中创建 再添加到常量池 (直接作用常量池 回去找常量池入口)
下面是JVM 详细过程
//   这个过程是在网上看到   
http://developer.51cto.com/art/200805/73338.htm   这是链接 这里不晓得怎么插入链接插入了没反应  要看的自己去复制吧我搞大点
对于String a = "haha" ,它的虚拟机指令:
0:   ldc     #16; //String haha   
2:   astore_1
3:   return

对于上面虚拟机指令,其各自的指令流程在《深入JAVA虚拟机》这样描述到(结合上面实例):

ldc指令格式:ldc,index

ldc指令过程:

            要执行ldc指令,JVM首先查找index所指定的常量池入口,在index指向的常量池入口,JVM将会查找CONSTANT_Integer_info,CONSTANT_Float_info和CONSTANT_String_info入口。如果还没有这些入口,JVM会解析它们。而对于上面的hahaJVM会找到CONSTANT_String_info入口,同时,将把指向被拘留String对象(由解析该入口的进程产生)的引用压入操作数栈。

astore_1指令格式:astore_1

astore_1指令过程:

要执行astore_1指令,JVM从操作数栈顶部弹出一个引用类型或者returnAddress类型值,然后将该值存入由索引1指定的局部变量中,即将引用类型或者returnAddress类型值存入局部变量1。

return 指令的过程:

从方法中返回,返回值为void。





回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马