黑马程序员技术交流社区

标题: String a= "aaa" 与 Stirng a= new String("aaa"), 请问具体差别 [打印本页]

作者: 别小乐    时间: 2014-5-7 20:45
标题: String a= "aaa" 与 Stirng a= new String("aaa"), 请问具体差别
今天开始看JAVA编程思想, 巩固基础。
看到这里
String a = "aa";与
String a = new String("aa");
就有个疑问,
在书中他是这样说的: String a = new String("aa")它不仅表示“给我一个新的字符串”, 而且通过提供一个初始化字符串, 给出怎么样产生这个String的信息.

但是在内存中,String a = new String("aa"); 与 String a = "aa";
有什么区别呢?  哪种更好?


作者: 最后的希冀    时间: 2014-5-7 21:30
本帖最后由 最后的希冀 于 2014-5-7 21:46 编辑

String a = new String("aa"),代表在堆内存中,创建了一个字符串对象,变量a指向该对象,而该对象又指向在常量池中的字符串常量。
而String a = "aa"代表直接由变量a指向常量池中的字符串,省去了中间的堆内存中的对象,因为new对象时,都会在堆中创建对象。
这就像如果有:
String s1 = "hello";
String s2 = "hello";
那么
System.out.println(s1==s2);
结果为true,因为他们的地址值是一致的,都指向常量池中的字符串常量。

String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1==s2);
结果则是false,因为他们都在堆中建立了对象,而对象之间的地址值不同
具体说哪个好,我觉得在单单说创建字符串而言,应该都差不多吧。不知道这样解释怎么样?


作者: thinkervsruler    时间: 2014-5-7 21:30
本帖最后由 thinkervsruler 于 2014-5-7 21:31 编辑

"aa",这个本身就是一个字符串对象,字符串对象是一个常量,一旦初始化,就不可更改,存在于内存常量池中。
前面String a "的意思就是在栈中创建一个字符串类型的变量a,
所以String a = "aa"的意思就是将字符串对象"aa"的内存地址赋给字符串变量a
String a = new String("aa")中有两个对象,一个是"aa"同上,另一个则是new String(),此对象创建时通过构造函数用字符串"aa"进行初始化,这两个对象内存地址是不一样的
至于哪一个好,要看具体环境吧,不过通过new创建字符串对象时,可以通过构造函数初始化,功能比较强大吧,范围应用也广些,LZ可以参考API中String类的构造方法

作者: 周大侠    时间: 2014-5-7 21:47
String a = "aa"; 先在内存中找是不是有"aa" 这个对象,

如果有,就让a指向那个"aa".如果内存里没有"aa",就创建一个新的对象保存"aa".

String a=new String ("aa") 就是不管内存里是不是已经有"aa"这个对象,

都新建一个对象保存"aa"
String a = new String("aa");是在堆里面建立的对象 String,a和"aa"
ab="aa";是查找栈里有没有"aa",如果有就用ab引用它,如果没有就把“aa”存进栈


String r ="dsds"; ---------------------生成一个对象 "dsds"
String r =new String ("dsd"); ---------------生成两个对象,"dsd"和new String ("dsd")

因为new String("dsd")的参数"dsd"本身就是一个字符串对象,new String("dsd")又返回一个字符串对象。

作者: 赵京    时间: 2014-5-7 22:11
String a = new String("aa")创建了两个对象,一个是在常量池中,一个是在堆内存中,常量池的为"aa";堆内存中为new String();
作者: 赵京    时间: 2014-5-7 22:15
1、String a = new String("aa");这个是创建了两个对象,常量池中一个为“aa”,堆内存中为:new String();
2、String a="aa",是只有一个对象,在常量池中。
所以如果拿节约内存来说的话,第二种可能好一些
作者: 别小乐    时间: 2014-5-7 22:32
最后的希冀 发表于 2014-5-7 21:30
String a = new String("aa"),代表在堆内存中,创建了一个字符串对象,变量a指向该对象,而该对象又指向在 ...

学习了!
作者: 别小乐    时间: 2014-5-7 22:34
最后的希冀 发表于 2014-5-7 21:30
String a = new String("aa"),代表在堆内存中,创建了一个字符串对象,变量a指向该对象,而该对象又指向在 ...

非常感谢您的解答!
作者: 别小乐    时间: 2014-5-7 22:43
thinkervsruler 发表于 2014-5-7 21:30
"aa",这个本身就是一个字符串对象,字符串对象是一个常量,一旦初始化,就不可更改,存在于内存常量池中。 ...

谢谢您的解答!
作者: 提菩--空    时间: 2014-5-7 23:46
String a = "aa";与String a = new String("aa");最根本的区别是:
String a = "aa";创建了一个字符串变量。a 是指向栈中的"aa";
而String a = new String("aa");创建的是一个对象。a 是指向堆中"aa"的地址。

作者: 蒋大帅    时间: 2014-5-11 21:23
string a=new String("aa")是在堆内存中创建了字符串aa,然后在栈内存中的变量a指向了栈内存中的字符串,其实String a=地址,String a等于的是字符串aa在栈内存的地址。;而string  a=“aa”是在内存中创建一个字符串直接赋值给变量a;
作者: 姜蕾蕾    时间: 2014-5-12 00:31
String a = "aa";
String a = new String("aa");
前者是直接赋值给a,数据由常量池管理,后者是新建了一个,放在堆内存中,String引用的地址不一样
作者: jsjchenlong    时间: 2014-5-12 01:13
支持2楼说的
作者: 李彦来    时间: 2014-5-12 07:35
最后的希冀 发表于 2014-5-7 21:30
String a = new String("aa"),代表在堆内存中,创建了一个字符串对象,变量a指向该对象,而该对象又指向在 ...

涨知识了....
作者: vincentgood    时间: 2014-5-12 13:46
这个其实很好理解,你看到有New的,就在堆内存开辟了新的空间,指向了常量池,也就是说,有new的就有两片内存空间,而直接赋值的,是直接在常量池中找,只有一片空间
作者: 苗润    时间: 2014-5-14 00:23
本帖最后由 苗润 于 2014-5-14 00:24 编辑

int a=3; 常量池
char c = 'a'; 常量池
boolean b = true; 常量池
byte byt = 2; 常量池
String str = "abc"; 在内存中"abc"存放在栈
String str1 = new String("abc"); 在内存中new String("abc")被存放在堆可以去百度下  “方法区” 这个概念 有详细解释的





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2