黑马程序员技术交流社区

标题: String的问题 [打印本页]

作者: 江杰    时间: 2012-5-21 19:20
标题: String的问题
字符串中
String str=new String("a");
String str="a";
这两句代码有什么不同的地方呢 》??我们一般什么时候用他们?
new都是在堆内存建立对象。
那String str="x" 有没有建立对象?是存在堆 内存中的吗???
作者: Fc10232    时间: 2012-5-21 19:26
我都不敢回答,万一版主扣我分了咱嫩,你百度一下自己不就知道了   先百度,百度搞不定的到论坛里问比较好, 小心被扣分。。。
作者: 江杰    时间: 2012-5-21 20:08
扣啥扣 扣了我的全给你
作者: 赵玮_Tom    时间: 2012-5-21 20:16
“a”这个对象是在常量池中,还是对内存中?我也搞不懂,坐等高人{:soso_e101:}
作者: 小小企鹅    时间: 2012-5-21 20:22
为了安全性和节省空间,String是不变的,执行String str = "a"时,Java虚拟机把str放到称为"String Pool"的存储区中,出现重复不会建立新的String,只会引用以存在的
作者: 谭威    时间: 2012-5-21 20:24
你这个问题好多个人问过当时可以是众说风云,网上也有一大把结论的。。
Java运行环境有一个字符串池,由String类维护。执行语句String str="a"时,首先查看字符串池中是否存在字符串"a",如果存在则直接将"a"赋给str,如果不存在则先在字符串池中新建一个字符串"a",然后再将其赋给str。执行语句String str=new String("a")时,不管字符串池中是否存在字符串"a",直接新建一个字符串"a"(注意:新建的字符串"a"不是在字符串池中),然后将其付给str。前一语句的效率高,后一语句的效率低,因为新建字符串占用内存空间。  from BAIDU
作者: 何拴绪    时间: 2012-5-21 20:25
new 出来的字符串对象是在堆内存里的,定义一个基础数据类型字符串是在堆内存的。
作者: 江杰    时间: 2012-5-21 22:18
谭威 发表于 2012-5-21 20:24
你这个问题好多个人问过当时可以是众说风云,网上也有一大把结论的。。
Java运行环境有一个字符串池,由Str ...

谢了,说的很详细
作者: 揭耀祖    时间: 2012-5-22 08:41
String str1 = "abc";
String str2 = new String("abc");

前者只有一个对象,而后者有两个对象,

所以 System.out.println(str1==str2);        //打印的是false
       System.out.println(str1.equals(str2));  //打印的是true
另外str1 与str2是一个类类型变量,而"abc"是一个对象。
作者: 刘聪    时间: 2012-5-22 13:02
站在前面诸位的肩膀上我总结一下哈:
1.“==”与equals;字符串直接赋值与new出字符串对象
前面一个原因大家都知道的,使用“==”,基本变量比较内容,对象比较内存地址。而equals方法比较要看是否重写了,没有重写,那就是object老大说的算了。后面一个,字符串直接赋值——就像谭威所说:JVM会将这种方式创建的字符串放入字符串池进行缓存。在一般情况下,字符串池中字符串对象不会被垃圾回收,当程序在此需要该字符串时,无需重新创建一个新的字符串,而是直接让引用变量指向字符串池中已有的的字符串。但new出来的不同——new出来的东东都在内存的中,而new出来的东东都是纯对象(虽然我们一再声称所有的东西都是对象,但这是我们java语义中实实在在new出来的对象),需要引用来标示它,因此对于他们的比较要基于equals。所以楼主的疑问:
new都是在堆内存建立对象。
那String str="x" 有没有建立对象?是存在堆 内存中的吗???
确切说str没有所谓的对象实例(最起码不是在堆中),而是在code区的字符串池里。
谭威所说提到的:“前一语句的效率高,后一语句的效率低,因为新建字符串占用内存空间。”即是因为前者可能只需要传递一下引用就可以了,而后者必须要在堆中老老实实的按照步骤开辟内存空间、给对象赋初值、将栈中的引用指向堆中的这个对象。
不过我看大家没有提到的一点是:关于字符串的使用可能也是java内存泄露的原因之一:当你不断使用一个相同的引用而不断改变其String字符串的值时就有可能发生这种情况:String str = "liu";   str = "liuCong"   str = "刘聪" 你不断的改变str的指向,而String类型是不会变的,因此它会在池里不断的创建出新的字符串,而原有的字符串就没有再用了,而且没有引用指向它们,这样垃圾回收不也定时,就可能会造成内存泄露。

作者: 林豪    时间: 2012-5-22 13:54
享元模式好像,第一个是存在堆中的,第二个是存在常量池中的

作者: 黑马—陈磊    时间: 2012-5-22 14:17
String str="a"; 声明一个String类型的 变量,变量的值是a
String str= new String("a");是声明一个String类型的对象,对象的内容是a

存放地方的区别:
第一个s是一个字符串常量,它存放在内存的静态存储区。
第二个s是一个对象,它是存放在堆中的。
用法的区别:
第二个是个对象,所以可以用String类中的所有方法,而第一个不是对象,它不可以操作String类中的方法




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