2.9 字符串的比较

187 阅读2分钟

2.9 字符串的比较

在字符串中:“==” 比较的是两个字符串是否相同,而equals()方法比较的是两个字符串的内容是否相同。

ex1:

String s1 = new String("java");
String s2 = new String("java");

System.out.println(s1 == s2);	//false
System.out.println(s1.equals(s2));	//true

此段代码创建的是两个对象,他们有不同的堆空间,因此"=="为false;但内容相同,因此.equals()为true;

ex2:

String s1 = new String("java");
String s2 = s1;

System.out.println(s1 == s2);	//true
System.out.println(s1.equals(s2));	//true`

此段代码中变量s1,s2指向的为同一堆空间,并且字符串内容相同,因此都为true;

ex3:

String s1 = "java";
String s2 = "java";
System.out.println(s1 == s2);	//true
System.out.println(s1.equals(s2));	//true`

此段代码中,字符创建方式为隐式创建,即,将String视为基本数据类型,因此,若字符串值相同,则s1,s2指向同一个对象;若不同,则指向不同对象。

ex4:

String s0 = "helloworld";
String s1 = "helloworld";
String s2 = "hello"+"world";
System.out.println(s0 == s1);	//true	可以看出s0跟s1是指同一个对象
System.out.println(s0 == s2);	//true`	可以看出s0跟s2是指同一个对象

此段代码中的s0和s1中的"helloworld”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而"hello”和"world”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中"helloworld”的一个引用。

ex5:

String s0 = "helloworld"; 
String s1 = new String("helloworld"); 
String s2 = "hello" + new String("world");
s3 = "aaa";
String s4 = s0 + s3;
System.out.println( s0 == s1 ); //false  
System.out.println( s0 == s2 ); //false 
System.out.println( s1 == s2 ); //false
System.out.println( s4 == "helloworldaaa" ); //false

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

s0还是常量池中"helloworld”的引用,s1因为无法在编译期确定,所以是运行时创建的新对象"helloworld”的引用,s2因为有后半部分new String(”world”)所以也无法在编译期确定,所以也是一个新创建对象"helloworld”的引用。

String s4=s0+s3是运行时才可知的,而"helloworldaaa"是在编译时就存放在常量池中的。在之前说过,String的所有函数都是返回的一个新字符串而不改变原字符串,因此+运算符会在堆中建立来两个String对象,这两个对象的值分别是"helloworld"和"aaa",也就是说从字符串池中复制这两个值,接着在堆中创建两个对象,然后再在栈空间建立变量s4,将 "helloworldaaa"的堆地址赋给s4。

github:github.com/ccy524946/t…