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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 唐巍 黑马帝   /  2012-3-16 01:42  /  2071 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

请看下面的代码:
class StringDemo
{
        public static void main(String[] args)
        {
                String s1="abc";
                String s2=new String("abc");
                System.out.println(s1==s2);//打印结果:false
                //s1和s2有什么区别?
                String s3="abc";
                System.out.println(s1==s3);//打印结果:true  
                //s3不是创建了一个新的对象,为什么比较结果会是true?
        }
}

7 个回复

倒序浏览
本帖最后由 谢明 于 2012-3-16 12:09 编辑

字符串很特别 其引用是放在栈里的  对象内容有创建的不同方式存在 常量池和堆中

使用new关键字,存放在堆中  --  String s2=new String("abc");  

而此处  String s1="abc";  运行时  是先检查常量池中是否有 "abc"  如存在就赋给s1  没有就在字符池新建后在赋给
回复 使用道具 举报
String s1="abc";这是在堆中创建了一个对象,并把对象的引用赋给s1.
String s2=new String("abc");这句话本来是创建两个对象的,但是在创建对象之前会查找常量池,常量池中已经创建了"abc"对象,所以在此只创建一个对象并把                         两个对象的引用赋给s2,所以为false;
String s3="abc";只是把常量池中"abc"的引用赋给了s3,所以为true
回复 使用道具 举报

我们先说说s1和s3为什么就一样了,当我们用创建了S1这个对象,并且为了以防你再次需要用别的变量名来使用同样值的对象的时候,我还得给你重新的搞出一个对象来,所以s1这个对象的值abc就作为了一个常量来存在于常量池中,当你再次用abc这个对象来初始化s3的时候,内存中只是把字符串常量池中的abc的地址给了这个s3,这样内存中就节省了空间。当你使用到==来判断s1==s3,那么它就会判断地址是否相同,这样,它就返回了true

我们再说说这个字符串s1和s2有什么区别吧,s1当中是一个对象。
而s2中却是两个对象,我们使用了abc作为参数了,它本身已经是一个对象了,因为它已经存在于字符串常量池中,本该直接把地址给了s2就算了,可是呢我们却使用了new这个关键字,这样我们就重新给了S2一个地址,所以它跟s1在判断==的时候,返回了false。
回复 使用道具 举报
"abc"是一个对象,存放在堆内存中
s1引用类型,在栈内存中
s2是一个引用对象,new相当于创建了一个对象
s3引用,在栈内存中,当发现堆内存中已经存在"abc"就不在开辟新的内存地址
回复 使用道具 举报
首先要分清堆内存和常量池的区别就明白了
//s1和s2有什么区别?
s1创建一个对象,s2创建两个对象               
//s3不是创建了一个新的对象,为什么比较结果会是true?
因为s1和s3都指向常量池中的"abc",常量池中的数据已经有"abc",又常量池中的数据不可改,常量池中再创建一个就没意义了
并不是所有字符串都会放在常量池中,能放在常量池中的字符串,必须是以字符串常量的身份进入的。如:
String str = "abc";
此时,常量池中自然会有“abc”,而且是在编译阶段进行的。
而String s1 = new String("abc");
这里的“abc”和常量池并没有什么关系。因为此时的"abc",存在于堆中,并不是常量池里的那个。更不会是从常量池复制过来的。
回复 使用道具 举报
s1中存了只有一个对象"abc",s2中存了两个对象"abc"和一个"new"对象,
所以s1==s2是用来比较对象是否一样的,当然s1==s2对象不一样为false。
s3中的"abc"对象和s1中对象是一样的,因为String对象一被建立就无法改变,
当两个引用的对象一样时,当然没必要建立两个对象去浪费内存资源。
所以s1和s3里的对象时一样的。
回复 使用道具 举报
对于你说的这个区别所在,我是这样理解的。
因为s1是字符串常量,它在内存中是存放在Data segement里,也就是常说的常量池里
而new一个对象出来,凡是new出来的对象引用在内存里都是放在堆内存里的
所以说当你用s1和s2比较相等肯定是false了

再看:s3是重新赋了值。因为s3它也是放在Data segement常量池里的。所以说当s1和s3进行比较的时候
就会在内存里查看它们是否属于同一个数据块!如果是则相等,很明显是相等的!我这样理解的不知道有
哪些地方不足!请指点...
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马