1.“==”和“equals”的区别
① “==”是一个比较运算符,既可以比较基本数据类型,也可以比较引用数据类型。对于基本数据类型,比较的是值;对于引用数据类型,比较的是地址值。
② “equals”是一个方法,只能比较引用数据类型,所有对象都会继承Object中的equals方法,如果没有重写Object类中的equals方法,equals方法和==号比较引用数据类型没有区别,重写后的equals方法比较的是对象中的属性。
③对于String类,由于重写了此方法,String中的equals比较的是字符串的内容是否相同,对于下面的例子:
String s1="abc";
String s2="abc";
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
输出结果: true
true
原因解释:对于String 对象,存在常量池,字符串“abc”存在常量池中,当再次定义s2并赋值“abc”时,会先看一下常量池中是否存在“abc”,如果存在,便将“abc”的地址赋值给s2,这样s1和s2同时指向了“abc”,所以利用==比较时,输出为true。
2.String中常量池
对于常量池,上面③中已将提及。注意下面的例子:
String s1=new String("abc");
上面的语句创建了几个对象??
正确答案是2个。
原因解释:一个在常量池中,一个在堆中(是常量池的副本)。
再举一个例子:
String s1=new String("abc");
String s2=new String("abc");
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
输出结果:false
true
上面的语句创建了几个对象??
正确答案是3个。
原因:一个在常量池中,另外两个在堆中(都是常量池中对象的副本)。当让此时,比较s1==s2时,输出结果为false 。因为s1和s2指向的地址不相同
- 注意下面的情况,如图所示
输出结果:
false
true
对于s1+“c” 如果是一个字符串对象和字符串相加,底层是利用StringBuffer的append方法实现了字符串拼接,然后又利用StringBuffer中toString方法转换成了String对象,然后将地址赋值给了s3,所以,s2和s3 的地址是不一样的。
String s1="a"+"b"+"c";
//java中采用了常量优化机制,自动转成了字符串"abc"
String s2="abc";
System.out.println(s1==s2);
输出结果:
true