Java中数据分为8种基本数据类型(byte,short,int,long,float,double,char,boolean)和引用类型。对于基本数据类型,只能用==来判断值是否相等;对于引用类型,==用来判断对象的地址,若在引用类内重写了equals()方法,则equals()为比较内容,若没有重写equals方法,则equals()为比较该对象的地址。
String s1,s2,s3 = "abc", s4 ="abc" ;
s1 = new String("abc");
s2 = new String("abc");
System.out.println("s1==s2:"+(s1==s2));//false,s1和s2在堆中为两个不同对象,地址不同
System.out.println("s1==s3:"+(s1==s3));//false,s3指向常量池中字符串常量,s1指向堆中对象
System.out.println("s3==s4:"+(s3==s4));//true,s3,s4均指向字符串常量池中abc
System.out.println("s1.equals(s2):"+(s1.equals(s2)));//true,String重写了equals()方法
System.out.println("s1.equals(s3):"+(s1.equals(s3)));//true,String重写了equals()方法
System.out.println("s3.equals(s4):"+(s3.equals(s4)));//true,String重写了equals()方法
注意:
StringBuffer s1 = new StringBuffer("a");
StringBuffer s2 = new StringBuffer("a");
System.out.println("s1.equals(s2):"+(s1.equals(s2)));//结果为false,StringBuffer未重写equals()方法
在基本数据的包装类型中:
public class TestEquals {
public static void main(String[] args)
{
Integer n1 = new Integer(30);
Integer n2 = new Integer(30);
Integer n3 = new Integer(31);
System.out.println(n1 == n2);//结果是false 两个不同的Integer对象,故其地址不同,
System.out.println(n1 == n3);//那么不管是new Integer(30)还是new Integer(31) 结果都显示false
System.out.println(n1.equals(n2));//结果是true 根据jdk文档中的说明,n1与n2指向的对象中的内容是相等的,都是30,故equals比较后结果是true
System.out.println(n1.equals(n3));//结果是false 因对象内容不一样,一个是30一个是31
}
}
更进一步:引用知乎上一段代码进行说明
String s1 = "sss111";
String s2 = "sss111";
System.out.println(s1 == s2); //结果为true,均指向常量池中字符串
String s1 = new String("sss111");
String s2 = "sss111";
System.out.println(s1 == s2); //结果为false,s1为堆上新创建的对象,故地址不相等
String s0 = "111"; //pool
String s1 = new String("111"); //heap
final String s2 = "111"; //pool
String s3 = "sss111"; //pool
String s4 = "sss" + "111"; //pool
String s5 = "sss" + s0; //heap
String s6 = "sss" + s1; //heap
String s7 = "sss" + s2; //pool
String s8 = "sss" + s0; //heap
System.out.println(s3 == s4); //true,s4在编译期已被合并放入字符串常量池,两者指向同一对象
System.out.println(s3 == s5); //false,s5在运行期被创建在堆上,是一个新对象
System.out.println(s3 == s6); //false,同上
System.out.println(s3 == s7); //true,由于s2为final类型,相当于常量,已在编译器组合好放入字符串常量池
System.out.println(s5 == s6); //false,两者为堆上的不同对象
System.out.println(s5 == s8); //false,两者为堆上的不同对象