返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #27575同步于 2013/10/28
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖
[问题]java内存:String s = "a"+new String("bc"); 这个是怎么
crystalhyh
2013/10/28镜像同步22 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
先在栈上定义S存储的是引用变量,字符串常量“a”和"bc"存在常量池中,建议看看http://wenku.baidu.com/view/b3f4f40002020740be1e9bdd.html比较详细。
补充一点,new string("bc")生成的对象是在堆上,然后栈上有一个指针指向这个对象
【 在 nuowei 的大作中提到: 】
: 先在栈上定义S存储的是引用变量,字符串常量“a”和"bc"存在常量池中,建议看看http://wenku.baidu.com/view/b3f4f40002020740be1e9bdd.html比较详细。
我把这条语句给你拆一下,不过不保证一定对哦。。
String s = null;\\在栈上开辟了一个对象S,其指向为null
String bc = new String("bc");\\在栈上创建一个对象bc,其引用指向为堆上的"bc";
String a = "a";\\在栈上创建一个对象a,其引用指向数据区的常量"a";
String abc = new String(a+bc);\\在栈上创建一个对象abc,指向堆上空间,至于堆空间是直接保存的还是引用的其他两个对象,我不太确定
s = abc;\\把abc的引用付给s
【 在 crystalhyh 的大作中提到: 】
: "a"应该是在常量池里的,但是"bc"应该在堆中,那这个s的引用到底指向哪里呢?
String a = new String("bc");
String b = new String("bc");
if (a == b)
System.out.println("true");
else
System.out.println("false");
output:
false
String a = "bc";
String b = "bc";
if (a == b)
System.out.println("true");
else
System.out.println("false");
output:
true
前者是在堆上“new”出对象,然后从常量池拷贝“bc”进去;后者是直接引用到常量池同一个常量;
0 new java.lang.StringBuilder [16]
3 dup
4 ldc <String "a"> [18]
6 invokespecial java.lang.StringBuilder(java.lang.String) [20]
9 new java.lang.String [23]
12 dup
13 ldc <String "bc"> [25]
15 invokespecial java.lang.String(java.lang.String) [27]
18 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [28]
21 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [32]
24 astore_1 [s]
上面是这句话编译后的字节码。楼上都忽略了一个问题,+操作符调用了StringBuilder。
【 在 yellowxz 的大作中提到: 】
: 0 new java.lang.StringBuilder [16]
: 3 dup
: 4 ldc <String "a"> [18]
: ...................
还是不知道s指向哪里的。。。
到底是常量池还是堆
宽泛的常量池的概念可以分为静态常量池和动态常量池。静态常量池指的是编译后class文件中的常量池,动态常量池是运行时解析class文件后得到,存放在堆中,就是狭义的常量池。
所以"a"和"bc"存放在常量池中。new String("bc")和s这两个引用存在栈中,对象实际存在堆中。
如果是String s = "a" + "bc",编译时已经能够确定s的值是abc,所以常量池中存"abc",s引用在栈中,指向常量池的"abc"。
这是我的理解,有错误欢迎指正。
【 在 crystalhyh 的大作中提到: 】
:
: 还是不知道s指向哪里的。。。
: 到底是常量池还是堆