1 ==
对于==,如果作用于基本数据类型(byte,short,char,int,long,float,double,boolean)的变量,则直接比较其存储的 “值”是否相等;如果作用于引用类型的变量,则比较的是所指向的对象的地址。
2 equals
equals方法不能作用于基本数据类型的变量。如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址。
java中所有的类都继承于Object这个基类,这个基类中定义了一个equals()方法,这个方法初始行为是比较对象的内存地址的,但一些类库中这个方法被覆盖掉,例如String Integer,Date这些类中的equals()有其自身的实现,不再是比较内存地址,而是比较值。
3 Java中经常用来做比较的是字符串,下面我们来看看字符串的比较
首先我们先看下String的重写的equals()方法的源码:
/**
* Compares this string to the specified object. The result is {@code
* true} if and only if the argument is not {@code null} and is a {@code
* String} object that represents the same sequence of characters as this
* object.
*
* @param anObject
* The object to compare this {@code String} against
*
* @return {@code true} if the given object represents a {@code String}
* equivalent to this string, {@code false} otherwise
*
* @see #compareTo(String)
* @see #equalsIgnoreCase(String)
*/
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
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;
}
度,若一样,则获取参数对象的char[]与原对象的char[]进行比较,若每个子元素都一样则返回true,否则返回false;
3.1
String str1 = "hello";
String str2 = "hello";
System.out.println(str1.equals(str2));
System.out.println(str1 == str2);
输出结果是:
true
true
String的equals()是比较字符串的内容,所以输出的结果是true。==是比较内存地址的,结果也是true,说明str1和str2的地址相同。
但是为啥地址相同呢?
Java有常量池,存储所有的字符串常量。String str1 = “hello”,java首先会在常量池查找是否有 “hello”这个常量,发现没有,于是会
创建一个 “hello”,并将其赋给str1。接着String str2= “hello,java同样会在常量池中查找 “hello”,这次常量池中已经有str1创建的 “h
ello”,所以不创建新的常量,将其地址赋给str2。因此,str1和str2就有了相同的地址。
3.2 new建立String对象
String str1 ="hello";
String str2 =new String("hello");
String str3 =new String("hello");
System.out.println(str1.equals(str2));
System.out.println(str1==str2);
System.out.println(str2==str3);
/**
output 输出
true
false
false
*/
new String()每次会在堆中创建一个对象,每次创建的对象内存地址都不同,故==不相等。但字符串内容是相同的,故equals()相等。
3.3 利用intern
String s1="Monday";
String s2 =new String("Monday");
s2 = s2.intern();
System.out.println(s1.equals(s2));
System.out.println(s1==s2);
输出结果为 true true
这是为什么?
java.lang.string 的intern()方法 返回的还是 s2的字符串,看上去没啥改变,但是它会检查常量池里面有没有字符串s2,
若有则将原先字符串的引用给s2,若没有则将字符串s2添加到常量池中,再将引用返回给s2