“==” 与 equals() 方法的区别
❀基本类型
byte、short、char、int、long、float、double、boolean
❀"==":比较
- 基本类型时,比较的是值是否相同
- 引用类型时,默认比较的是地址值是否相同
❀基本类型比较
int i = 1, j = 2,a = 1;
System.out.println(i == j);//false
System.out.println(i == a);//true
System.out.println(j == a);//false
❀引用类型比较
String str = new String("1");
String str1 = new String("1");
String str2 = str1;//str与str2引用了同一个地址值下的"1";
System.out.println(str == str1);//false
System.out.println(str1 == str2);//true
System.out.println(str == str2);//false
❀"equal(Object obj)"
❀基本类型
基本类型不能调用equals(Object obj)方法
❀引用类型
//学生类(未重写equlas(Object obj)方法)
public class Student{
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
//测试类
public class EquestTest01{
public static void main(String[] args) {
Student s1 = new Student();
s1.setAge(10);
s1.setName("xiao");
Student s2 = new Student();
s2.setAge(10);
s2.setName("xiao");
Student s3 = s1;
s3.setAge(12);
s3.setName("hong");
System.out.println(s1.equals(s2));//false
System.out.println(s2.equals(s3));//false
System.out.println(s1.equals(s3))//true
}
}
Object类是所有类的父类,当我们调用equals(Object obj)方法进行两个引用对象进行比较的时候,默认使用的是Object的equals(Object obj)方法,下面我们看看Object的equals(Object obj)方法的源码:
根据源码分析,当引用对象调用Object的equals(Object obj)方法时,实际是还是在使用“==”进行地址值比较,由测试类结果所得,使用equals(Object obj)方法时,及时s1与s2内容完全相同,但结果为false,而s3引用了s1的地址值后,即使内容不同,s3与s1仍然为true,可见Object的equals(Object obj)方法默认比较的仍是地址值。
//学生类(重写equals(Object obj))
public class Studnet{
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
//测试类
public class EquestTest01{
public static void main(String[] args) {
Student s1 = new Student();
s1.setAge(10);
s1.setName("xiao");
Student s2 = new Student();
s2.setAge(10);
s2.setName("xiao");
Student s3 = s1;
s3.setAge(12);
s3.setName("hong");
System.out.println(s1.equals(s1));//true
System.out.println(s1.equals(s2));//true
System.out.println(s2.equals(s3));//false
System.out.println(s1.equals(s3))//false
}
}
当我们重写了equals(Object obj)方法后,会发现测试类调用的的equals(Object obj)方法,使用的是String的equals(Object obj)方法,那String的equals(Object obj)方法源码是怎么回事儿呢?下面我们看看Sting的equals(Object obj)方法的源码:
根据源码分析,当s1.equals(s1)时,this == anObject;返回true;除此之外,判断当前anObject是否是String类的实例,如果不是则返回false,如果是则继续,将该anObject转化为String对象,判断当前对象值的长度与要比较的对象的值长度是否相同,如果相同,在将它们的值存放感到char数组中,然后遍历,挨个比较这两个char数组中的字符,如果有一个不同,则返回false,直到每个字符完全相同才返回true。所以当引用对象再执行equals(Object obj)方法时,实际是比较其值是否相同,不再是比较地址值。