①判断定义为String类的s1和s2是否相等
String s1="abc";
String s2="abc";
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
运行结果:
true
true
根据代码顺序,先在常量池中创建”abc“,并指向s1,而后在创建s2时,由于常量池中已经存在”abc“,如果常量池中存在相同的数据,只需引用就行,而不需要再创建。”==”在这里比较的是对象引用,故结果为”true”,String 中的equals方法经过重写后操作为“比较此字符串与指定的对象。当且仅当该参数不为 null,并且是表示与此对象相同的字符序列的 String 对象时,结果才为 true”。很明显,s1和s2的字符序列相同,故而结果为true。
②下面这句话在内存中创建了几个对象?
String s1=new String("abc");
该语句首先String s1是声明,new String(“abc”)先在常量池中查找,若没有则创建“abc”,而后通过new在堆内存中创建对象,把“abc”拷贝赋值。String 定义为初始化一个新创建的 String 对象,表示一个与该参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的一个副本。所以在常量池和堆内存各创建了一个对象,两个对象的地址值不一样。
③判断定义为String类的s1和s2是否相等
String s1=new String("abc");
String s2="abc";
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
由上面的二个列子可知,它们一个在堆内存中,一个在常量池中,所以运行结果s1==s2为false,s1.equals(s2)为true。
④判断定义为String类的s1和s2是否相等
String s1="a"+"b"+"c";
String s2="abc";
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
java中常量优化机制,编译时s1已经成为“abc”在常量池中查找创建,s2不需要再创建。
所以使同一个引用地址,而值也全部相同,运行结果为true,true
⑤判断定义为String类的s1和s2是否相等
String s1="ab";
String s2="abc";
String s3=s1+"c";
System.out.println(s3==s2);
System.out.println(s3.equals(s2));
在官方提供的文档说明中,Java 语言提供对字符串串联符号(”+”)和其他对象到字符串的转换的特殊支持。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的,字符串转换是通过 toString 方法实现的。在本题中,先在常量池中创建”ab“,地址指向s1,再创建”abc”,指向s2。对于s3,先创建StringBuilder(或 StringBuffer)对象,通过append连接得到“abc”,再调用toString()转换得到的地址指向s3。故(s3==s2)为false。而s3.equals(s2)比较的是值,结果为true。