java里用“==”比较两个字符串的问题

public class f {
public static void main(String[] args){
String S1=new String("abc");
String S2="abc";
String S3="abc";
String S4=new String("abc");
System.out.println(S1==S2);
System.out.println(S2==S4);
System.out.println(S2==S3);
System.out.println(S1==S4);
}
}

运行的结果是:
false
false
true
false
大家给我讲讲为什么是这个结果

* "abc"---------存储的地方叫常量字符串池,是共享字符串的;
* new String("abc")对象-------------存放在堆;
* S1,S2,S3,S4--------------引用在栈内存中;
* String 类创建的时候,检查字符串"abc"是否在pool中已经存在,存在的话就会共享。
String S1=new String("abc");做了以下动作:
1 定义一个S1引用,指向对象new String("abc");
2 而对象new String("abc"),又使用了常量字符串池中的"abc",也可以说指向;
----------------------------------------
String S2="abc";
定义一个S2引用,指向常量字符串池的"abc";[有存在的就共享]
String S3="abc";
定义一个S3引用,指向常量字符串池的"abc";[有存在的就共享]
String S4=new String("abc");
1 定义一个S4引用,指向对象new String("abc");这会在堆内存中再开一个对象,此对象也是志向常量池中的"abc";但对象各是各,它们的堆内存地址可不样。
-----------------------------------------------
再明确一点就是:==比较的是内存地址,栈内存中的引用存放的内容就是其所志向的对象的堆内存地址,也就是S1,2,3,4[可以这么理解]
这样看来;S2==S3不用说了;S1,S4的内存地址也不一样;
你看吧!
温馨提示:内容为网友见解,仅供参考
第1个回答  2010-12-22
String s2 = "abc" 表明s2与一个“字符串常量”对应 这个字符串常量是在编译期确定的 因此只要是跟相同的字符串常量对应的变量都相等 这也就是你的s2==s3为true的原因

String s1=new String("abc")这里用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

更详细的讲解 参照 http://zhidao.baidu.com/question/103877234.h
第2个回答  2010-12-22
内存上三块空间,分别存了三个“abc”,S1指向一个,S4指向一个,S2和S3指向同一个,也就是说S2和S3引用的是同一对象,“==”是判断二者是否指向同一对象,或者说判断二者是否引用了同一个对象
第3个回答  2010-12-22
只要new的话就会新创建一个字符串对象。
String S2="abc";
String S3="abc";
s2和s3引用的是一个字符串,因s3会到字符串池中找知否有“abc",将其引用直接给s3。
就这么简单
第4个回答  推荐于2017-11-23
字符串是一个比较特殊的对象。
字符串之所以特殊,是因为java会在内容中为String类型的对像开辟一个空间,我们叫他串池!
字符串对象的创建之后会被放入到串池中。
串池有一个特点,就是对于相同对象,池中只存储一份。
那么串池把神马样的String看做是相同的String呢。请看:
String a="abc";和String b="abc" 对于这样的类型的声明方式(不是new出来的)串池把他们看做一个对象,所以池中只存储一分,只是有a 和b 两个引用罢了!
对于String只要用new关键字new出来的string,都是单独的一个对象。
而“==”号,他是用来比较对象的内存地址,所以只要用==号来比较string,只要不是自己比自己,那肯定是false。
而String中的equls方法已经做了处理,他是比较内容,所以要比较string的内容的时候而不是地址的时候,那就用它吧!本回答被提问者采纳
相似回答