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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 江杰 初级黑马   /  2012-5-21 19:20  /  2917 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

字符串中
String str=new String("a");
String str="a";
这两句代码有什么不同的地方呢 》??我们一般什么时候用他们?
new都是在堆内存建立对象。
那String str="x" 有没有建立对象?是存在堆 内存中的吗???

11 个回复

倒序浏览
我都不敢回答,万一版主扣我分了咱嫩,你百度一下自己不就知道了   先百度,百度搞不定的到论坛里问比较好, 小心被扣分。。。
回复 使用道具 举报
扣啥扣 扣了我的全给你
回复 使用道具 举报
“a”这个对象是在常量池中,还是对内存中?我也搞不懂,坐等高人{:soso_e101:}
回复 使用道具 举报
为了安全性和节省空间,String是不变的,执行String str = "a"时,Java虚拟机把str放到称为"String Pool"的存储区中,出现重复不会建立新的String,只会引用以存在的
回复 使用道具 举报
你这个问题好多个人问过当时可以是众说风云,网上也有一大把结论的。。
Java运行环境有一个字符串池,由String类维护。执行语句String str="a"时,首先查看字符串池中是否存在字符串"a",如果存在则直接将"a"赋给str,如果不存在则先在字符串池中新建一个字符串"a",然后再将其赋给str。执行语句String str=new String("a")时,不管字符串池中是否存在字符串"a",直接新建一个字符串"a"(注意:新建的字符串"a"不是在字符串池中),然后将其付给str。前一语句的效率高,后一语句的效率低,因为新建字符串占用内存空间。  from BAIDU
回复 使用道具 举报
new 出来的字符串对象是在堆内存里的,定义一个基础数据类型字符串是在堆内存的。
回复 使用道具 举报
江杰 初级黑马 2012-5-21 22:18:25
8#
谭威 发表于 2012-5-21 20:24
你这个问题好多个人问过当时可以是众说风云,网上也有一大把结论的。。
Java运行环境有一个字符串池,由Str ...

谢了,说的很详细
回复 使用道具 举报
String str1 = "abc";
String str2 = new String("abc");

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

所以 System.out.println(str1==str2);        //打印的是false
       System.out.println(str1.equals(str2));  //打印的是true
另外str1 与str2是一个类类型变量,而"abc"是一个对象。
回复 使用道具 举报
站在前面诸位的肩膀上我总结一下哈:
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类型是不会变的,因此它会在池里不断的创建出新的字符串,而原有的字符串就没有再用了,而且没有引用指向它们,这样垃圾回收不也定时,就可能会造成内存泄露。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
享元模式好像,第一个是存在堆中的,第二个是存在常量池中的
回复 使用道具 举报
String str="a"; 声明一个String类型的 变量,变量的值是a
String str= new String("a");是声明一个String类型的对象,对象的内容是a

存放地方的区别:
第一个s是一个字符串常量,它存放在内存的静态存储区。
第二个s是一个对象,它是存放在堆中的。
用法的区别:
第二个是个对象,所以可以用String类中的所有方法,而第一个不是对象,它不可以操作String类中的方法
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马