黑马程序员技术交流社区

标题: 结果为什么是这样的? [打印本页]

作者: 李深山    时间: 2012-3-21 14:49
标题: 结果为什么是这样的?
public class TestString {
       public static void main(String[] args){
              String n = "I Love Java";
              String m = "I Love Java";
String s = new String( "I Love Java") ;           
              System.out.println(n==m);//这个为什么是true?
System.out.println(n==s);//这个为什么又成了false?
       }
}
为什么会有不一样的结果?
作者: 王思兰    时间: 2012-3-21 15:06
n在数据区里创建了一个字符串"I Love Java",m就不会再创建了,会直接指向"I Love Java"
s指向堆内存中new出来的对象,所以第一个为true,第二个为false
作者: ♂诸侯♂    时间: 2012-3-21 15:18
本帖最后由 ♂诸侯♂ 于 2012-3-21 15:25 编辑

char只能用==
equals是Object的方法
字符串比较相等一般用equals,不要用==

String s=“4543”;
String a=“4543”;
s.equals(a);


String str1="ab";
String str2="abc";
if(str1.equals(str2)==false ){
System.out.println("字符串不相等");
}else{
System.out.println("字符串相等");
}


String str1="ab";
String str2="abc";
if(str1.equals(str2) ){   //str1.equals(str2)==false 是多次一举, str1.equals(str2)本事就是布尔值了
System.out.println("字符串不相等");
}else{
System.out.println("字符串相等");
}
作者: 魏昂    时间: 2012-3-21 15:22
本帖最后由 魏昂 于 2012-3-21 15:36 编辑

因为 n和m 每个分别创建了一个对象内容是I Love Java
而s 先创建了一个匿名对象 内容是I Love Java 然后又把这个对象给了新的引用对象s
因此 n和m是true 而n和s是false了  ,明白了吗?
作者: 谢明    时间: 2012-3-21 15:25
字符串的引用呢 是放在栈内存中的 对象内容由创建的不同方式存在 常量池和堆中

使用new关键字,存放在堆中  --  String s = new String( "I Love Java") ;  
而此处  String n = "I Love Java";运行时  是先检查常量池中是否有 "I Love Java"  如存在就赋给n  没有就在字符池新建后在赋给
String m = "I Love Java";
m同上
==  判断是否为同一个对象
作者: 李深山    时间: 2012-3-21 15:25
没有{:soso_e109:},真是不好理解呀
作者: 魏昂    时间: 2012-3-21 15:41
李深山 发表于 2012-3-21 15:25
没有,真是不好理解呀

String n = "I love java";这条语句和String m = "I love java";都是创建了唯一的对象,而对象的内容也相同。
而 String s = "I love java"; 这条语句实际上创建了两个对象。一个是内容是"I love java"的匿名对象 和引用对象s 故而 n==s 是false。 懂了吗?
作者: 谢明    时间: 2012-3-21 15:48
{:soso_e136:}  加6分  有木有!
作者: 泮和顺    时间: 2012-3-21 16:25
n m指向的都是同一个字符串 字符串在常量池中
new出来的另外开辟堆内存 让他指向字符串 其实是有两个对象
作者: 周建    时间: 2012-3-21 20:07
String n = "I Love Java";这里在堆内存创建了一个字符串对象,类类型变量n存储在栈内存中;此时n中存储的是对象的地址值;若再次定义一个对象 String m = "I Love Java";此时系统不会重新创建对象,而是把已有的对象地址值复制给新的类类型变量m,所以m==n;
而String s = new String( "I Love Java") ;在Java中new就代表重新创建一个实例对象,也就是有一个新的地址值,此时类类型变量s里面就存储了一个不一样的地址,所以s!=n;
需要强调一下String s = new String( "I Love Java") ;实际上有两个对象,即new String()所创建的对象中存储了另一个对象"I Love Java";

作者: 孙国军    时间: 2012-3-21 23:37
你使用"=="号表示的两个String变量的在内存中的地址值相等
m=n为true是应为他们两个的地址值是相同的,指向同一个内存
而s是你new的一个变量,他会从新开辟一个内存空间,他的地址不同,
所以n==s为false
作者: 贾旭    时间: 2012-3-21 23:54
n和m比较结果为True是因为:n是一个类类型变量,"I LOVE JAVA"是一个对象。而字符串的特点是一旦初始化就不可改变。
n和s比较结果为false是因为:“I LOVE JAVA”是一对象,s是一个new的新对象。
你如果用equals比较结果就为true了。equals用于判断字符串是否相同。
几句话也说不清,你仔细看看毕向东老师的第13天视频01--String概述就OK了。
作者: 张红    时间: 2012-3-22 15:05
string s="I Love Java"只有1个String Object对象。可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈内存中数据的实际情况来决定是否有必要创建新对象.
而对于string s  = new  string ( "I Love Java")  则在堆内存中创建了新对象,
一个是“I Love Java”,一个是指向“I Love Java”的引用对像s。加重了程序的负担。

但是 ,string类用于比较值的话用equals,==就是比较了内存地址值。而n==m因为它们并未创建新的对象  ,所以指向同一个内存地址 。so true。n==s     s是新创建的对象,它们 值相同,但s是在堆内存中新创建的,很显然地址值不相同 。
你看以下代码可知:

class TestString {
       public static void main(String[] args){
              String n = "I Love Java";
              String m = "I Love Java";
              String s = new String( "I Love Java") ;           
              System.out.println(n==m);
              System.out.println(n.equals(m));
              System.out.println(n==s);
              System.out.println(n.equals(m));
       }
}

输出结果:
true
true
false
true
作者: 张锦萍    时间: 2012-3-22 15:56
String n = "I Love Java";
  String m = "I Love Java";只里面只有一个对象就是字符串常量 "I Love Java",n和m分别指向这个对象,
而new String( "I Love Java");new了一个新的对象,重新分配了一个内存空间,s就指向了另一个对象,但是他们值相等,equals比较时相等。





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