前段时间水群跟群友讨论到'=='和'equals'的区别,抽空整理记录下。
下面是测试代码
System.out.println(1==1); System.out.println(new Integer(1)==new Integer(1));
得到的结果是
true false
结论:对于基础类型(int、boolean、char)这类,'=='就是比较他们的值。而对于对象,它比较的是这个对象指向的地址,简单来讲就是等号两边是不是同一个对象,是返回true,否则返回false。测试用例中new出了两个Integer对象,虽然值相同,但是显然这两不是同一个对象。
先看Object类的'equals'方法
public boolean equals(Object obj) { return (this == obj); }
可以看到,Object类的'equals'方法只是对'=='做了简单的封装。
所以Java里的类,如果没有重写过'equals'方法,那么'=='和'equals'方法是没有本质区别的。
public boolean equals(Object anObject) { if (this == anObject) { //先用==判断这两是不是同一个对象 return true; } if (anObject instanceof String) { //判断传入对象是否是String类的实例 String anotherString = (String)anObject;//强制转换为String类型 int n = value.length; if (n == anotherString.value.length) {//判断当前对象和传入对象的长度是否一致 char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) {//逐个比较两个字符串里的字符 if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
public boolean equals(Object obj) { if (obj instanceof Integer) {//判断传入对象是否是Integer类的实例 return value == ((Integer)obj).intValue();//比较两者的值 } return false; }
public final boolean equals(Object o) { if (o == this)//先用==判断这两是不是同一个对象 return true; if (o instanceof Map.Entry) {//判断传入对象是否是Map的实例 Map.Entry<?,?> e = (Map.Entry<?,?>)o; if (Objects.equals(key, e.getKey()) && Objects.equals(value, e.getValue()))//分别比较两者的key和value是否一致,用的Objects的equals return true; } return false; }
String a="123"; String b="123"; System.out.println(a==b);
输出结果是true
这是因为a和b指向的都是“123”这个字符串,内存里没有生成一个新的“123”字符串。
在代码里写死的这些字符串,在程序运行的时候会自动在内存里创建一片空间,在拿它给其他String对象赋值的时候,只是简单地将对象的指针指向这个空间。
上面代码等同于
String s = new String("123"); String a=s; String b=s; System.out.println(a==b);
很显然,a和b其实都是s,所以输出true。
C#中'equals'情况与Java相似,但是'=='略有区别。
在C#中,String类是特殊的,'=='与Java中String类的'equals'方法相似,也是先比较两者的地址是否一致,不一致再比较两者的值是否一致。