Java、C#中'=='和'equals'的区别
Java、C#中”==”和”equals”的区别
前段时间水群跟群友讨论到”==”和”equals”的区别,抽空整理记录下。
Java
先说”==”
下面是测试代码
System.out.println(1==1);
System.out.println(new Integer(1)==new Integer(1));
得到的结果是
true
false
结论:对于基础类型(int、boolean、char)这类,”==”就是比较他们的值。而对于对象,它比较的是这个对象指向的地址,简单来讲就是等号两边是不是同一个对象,是返回true,否则返回false。测试用例中new出了两个Integer对象,虽然值相同,但是显然这两不是同一个对象。
然后是”equals”
先看Object类的”equals”方法
public boolean equals(Object obj) {
return (this == obj);
}
可以看到,Object类的”equals”方法只是对”==”做了简单的封装。
所以Java里的类,如果没有重写过”equals”方法,那么”==”和”equals”方法是没有本质区别的。
下面是一些常用的重写了”equals”方法的类
String类源码
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;
}
Integer类源码
public boolean equals(Object obj) {
if (obj instanceof Integer) {//判断传入对象是否是Integer类的实例
return value == ((Integer)obj).intValue();//比较两者的值
}
return false;
}
HashMap类
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的特殊情况
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#
C#中”equals”情况与Java相似,但是”==”略有区别。
在C#中,String类是特殊的,”==”与Java中String类的”equals”方法相似,也是先比较两者的地址是否一致,不一致再比较两者的值是否一致。