String s1="abc";
String s2="abc";
String s3=new String("abc");
String s4=new String("abc");
System.out.println(s1==s2);
System.out.println(s3==s4);
System.out.println("abc"=="abc");
为什么会出来如下结果:
true
false
true
String s1="abc";和String s1=new String("abc");定义有什么区别吗?
String s2="abc";
String s3=new String("abc");
String s4=new String("abc");
System.out.println(s1==s2);
System.out.println(s3==s4);
System.out.println("abc"=="abc");
为什么会出来如下结果:
true
false
true
String s1="abc";和String s1=new String("abc");定义有什么区别吗?
没有区别。
new String("abc") == new String("abc") is false
String a = new String("abc"); String b = a; a == b is true其次,String class覆写了Object class中的equals() method,这使得调用String.equals() method时,实际比较的是String class的内部值,而不是她的引用地址,所以
new String("abc").equals(new String("abc")) is true
new String("abc").equals("abc") is true
"abc".equals(new String("abc")) is true最后,String class在JAVA中是一个比较特殊的对象,由于她非常常用,并且可看做是一个char array,所以JAVA中对String class做了一些有趣的设计,以简化她的操作1. 你可以通过 = 赋值符号来对String object进行赋值,而不必每次都使用new操作符生成一个新对象,所以简单的说
String str = new String("abc") 与
String str = "abc";
等价2. 但是以上二者又不完全等价,因为String太过常用,JAVA类库的设计者在实现时做了个小小的变化,即采用了享元模式,关于享元模式的具体内容可参见《设计模式 —— 四人帮的那本》或者《JAVA与模式——阎宏》,采取了享元模式后,每当生成一个新内容的字符串时,他们都被添加到一个共享池中,当第二次再次生成同样内容的字符串实例时,就共享此对象,而不是创建一个新对象,这样的做法仅仅适合于通过 = 符号进行的初始化,比如:
String str1 = "abc"; String str2 = "abc";
str1 and str2 事实上共享了"abc"实例,所以 str1 == str2 is true
但是
String str1 = new String("abc"),当使用new关键字后,JVM会强迫系统再次生成一个新的字符串实例而不是共享原先存在的实例,所以
String str2 = new String("abc")
str1 == str2 is false为了保证共享对象后的数据一致性问题,类库的设计者还采取了不变模式来约束String对象。最后,为了安全其间,对String对象的比较应该采用equals method而不是 ==,这样无论如何都不会发生比较问题,同时也可以防止因为分布式、持久化或者clone等操作后,导致对象被复制并无法返回期望的 == 结果。@.@||~
直接写的时候是在串池里面表示的当你在定义一个想同的对象的时候它会自己在池里面找如果没有才创建 有的话就直接返回它的地址 所以s1==s2
你可以用intern()方法得到堆里面对象的池地址比如s3=s3.intern();这个时候s1==s2==s3其实都是同一个对象
String s1="abc";
String s2="abc";//这里只有一个对象;s1,s2是共享一个常量对象
String s1=new String("abc");//这是在堆中实实在在new一个对象;
当你不是用new 的方法创建的String对象,有相同的值的时候对应的是串池中的同一个值所以地址是同一个,用==比较的是两个对象的地址所以第一个是true
用new 生成的String对象是在堆空间生成的两个不同的String对象 自然物理地址是不一样的所以用==比较一定是不同的
至于第三个同第一个一样,String s1="abc";方式会在串池中生成的一个字符串,当你不用他的时候他不会被垃圾回收,而是在系统执行垃圾回收前一直存在着。System.out.println("abc"=="abc");它其实比较的是同一个对象,所以一定也是true的
不用new关键字的,是把变量指向常量内存,比如前面两个
String s1="abc";
String s2="abc";
它们是建立s1和s2的隐式对象,指向“abc”这个常量的内存
当你用new关键字的时候,如后面两个
String s3=new String("abc");
String s4=new String("abc");
就创建事例对象s3和s4,并且把“abc”指向对象s3和s4而“==”运算符的作用(一定程度上讲)就是比较他们的内存空间是否相同的,我们看前面两个建立的,他们的内存空间都是一样的在“abc”这个常量里面,所以他们是相同的内存空间;而后面两个是自己的内存,并且把常量“abc”指向自己,其实s3和s4就不是同个内存了,那么就会出现以下效果:
s1=s2 true 相同内存
s1=s3 false 不同内存
s3=s4 false 不同内存
s1="abc" true 相同内存
s3="abc" false 不同内存这样说你应该明白了吧???
String b = "hello";
System.out.println(a==b);由上可知:代码输出结果 true而对于new String("....")的形式,本来"..."已经就是一个字符串对象,并存在于文字池中,而new String()会将文字池中的"...."拷贝到堆(heap)中,并把堆(heap)中对象的引用交给字符串引用变量.所以这条语句会产生两个 String对象.String c = new String("hello");
String d = new String("hello");
System.out.println(c==d);由上可知:代码输出结果为 false,引用变量c,d分别指向的是堆(heap)中不同的字符串对象.详细的见我的blog:http://blog.csdn.net/nirvana_li/archive/2006/07/21/952240.aspx
深圳java程序员博客,为你提供多方面资料http://drivemewild.blogchina.com
String s2="abc";
//s1,s2是同时引用字符串"abc"的参考值String s3=new String("abc");
String s4=new String("abc");
//s3,s4是不同的对象 ,因为new了System.out.println(s1==s2);
//== 是比较两个对象是否相等 此处为同一对象,因此结果为true
System.out.println(s3==s4);
//不同对象 结果为false
String str1="123"; //创建了一个对象 123
String str2="abc"; //创建了两个对象 一个abc 一个指向abc的引用str2如果再定义一个String str3="123"; 其实str1 和 str3是指向同一个对象的
谢谢了
看下面的语句:
String str1= "abc";//str1存放"abc"的首地址
String str3= "abc";//str1存放"abc"的首地址
等效于
char data[]={`a`,`b`,`c`};
String str1=new String(data);
String str3=new String(data);
但是在下面的这几条语句中的str1和str3却是不同的。问题出在 String(char[] value)这个构造函数。因为构造了两次,所以每次分配的堆内存必然是不相同的。这就导致了栈内存中表示堆内存首地址的str1,str3是不同的。这就是LZ为什么s3==s4 false
s1==s2 true的原因。
String s2="abc";
String s3=new String("abc");
String s4=new String("abc");"abc"是个字符串,s1,s2都指向了他,所以相等s3里的“abc”仅仅是内容,这里的“abc”只属于s3,s4与s3相同,都是独立的引用
所以他们不相等
s1==s2
java 以new 显式指出分配空间的动作,所以new出来的两个对象分别指向不同的两块存储区
s3!=s4