java中与很多有意思又值得深究的点。
写这篇文章呢,是由于在百度知道中看到一个问题:怎样比较两个对象是否相同。这又使我想到了另外一个问题,== 和 equals有什么不同?写了几行代码,看了几篇文章,将见解列出来,分享。
在阐述之前请大家先看一段代码。
public classEquals {public static voidmain(String[] args) {
Integer int1= new Integer(1);
Integer int2= new Integer(1);
String str1= new String("Hello World");
String str2= new String("Hello World");if(int1==int2){
System.out.println("int1 == int2");
}if(int1.equals(int2)){
System.out.println("int1 equals int2");
}if(str1==str2){
System.out.println("str1 == str2");
}if(str1.equals(str2)){
System.out.println("str1 equals str2");
}
}
}
输出结果:
int1 equals int2
str1 equals str2
各位也都知道,java中万物皆对象。那么也有,java中所有声明出来的对象全都继承Object对象。
第一次看到这段代码的输出结果我也是很吃惊的,很奇怪啊。我奇怪的地方有两点:
1、int1和int2的值明明相等,可是却不是==,非常奇怪。
2、int1和int2明明是两个对象,可是却能equals相等,更加奇怪。
对于1,我奇怪的是==比较的是数值相等啊。可是两个明明相等的值却不想等。可是后来查了很多资料之后看到了这么一句话:
对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址;(引用,原文链接在文末)
这就很明了了,也就是说==在比较的int1和int2的时候比的对象的地址,那么分别两次new出来的对象地址自然不可能相同。
对于2,
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
则可以看到,在String或者Integer中都可以看到,java对Object的equals方法进行了重写都分别比较的是对象的值。所以才会有第二种结果的产生,其实仔细想想也是,总不可能没有能够正确比较的方法吧。
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
总结,即:
1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容