首页 > 代码库 > Java之equals和==详解

Java之equals和==详解

两者的区别:

A:==
基本类型:比较的是值是否相同
引用类型:比较的是地址值是否相同
B:equals()
只能比较引用类型。

默认情况下,比较的是地址值是否相同,因为我们可以看源代码可以看到,在Object类中该方法的比较是用==比较的

public boolean equals(Object obj) {
        return (this == obj);
    }
比如当我们想要比较两个引用类型的某些内容是否相等(student类中学生姓名或者年龄是否相等),这时比较地址值是没有意义的,所以我们一般会重写该方法,因为该方法是Object类中的方法,一般用快捷键重写equals方法(Alt+Shift+S)。在系统API中的类都自己重写了equals方法,所以直接调用比较的实际上是比较对象的值是否相等,而不是比较对象的地址值。而我们自己写的类。比如学生Student类等等,如果不重写equals方法,则默认是比较对象的地址值,所以要比较对象的值时候都会重写该方法。如下代码:

public class Equal {

	public static void main(String[] args) {
		Integer a1 = new Integer(10);
		Integer a2 = new Integer(10);
		System.out.println(a2.equals(a2));//true
		System.out.println(a1 == a2);//false
		System.out.println("------------");
		String a = new String("ha");
		String b = new String("ha");
		System.out.println(a.equals(b));//true
		System.out.println(a == b);//false
		System.out.println("------------");
		<span style="color:#ff0000;">Student s1 = new Student(10);
		Student s2 = new Student(10);
		Student s3 = s1;
		System.out.println(s1.equals(s3));//true
		System.out.println(s1.equals(s2));//false
		System.out.println(s1 == s2);//false</span>
		System.out.println("------------");
		int s4 = 3;
		int s5 = 3;
		//System.out.println(s4.equals(s5));//会报错,equals只能比较引用类型
		System.out.println(s5 == s4);//true
		System.out.println("------------");
		String s6 = "ha";
		String s7 =new String("ha");
		System.out.println(s6.equals(s7));//true
		System.out.println(s6 == s7);//flase
		System.out.println("------------");
		ArrayList list1 = new ArrayList();
		list1.add("aa");
		ArrayList list2 = new ArrayList();
		list2.add("aa");
		System.out.println(list1.equals(list2));//true
		System.out.println(list1 == list2);//false
		System.out.println("------------");
		ArrayList list3 = new ArrayList();
		list1.add("aa");
		ArrayList list4 = new ArrayList();
		list2.add("bb");
		System.out.println(list1.equals(list2));//false
		System.out.println(list1 == list2);//false
		//==在基本类型中比较的是值,在引用类型中比较的是地址值
	}

}

class Student {
	private int age;
	public Student(int age) {
		this.age = age;
	}
	//没有重写equals方法,则调用的是Object中的,默认比较地址值
}
在Student类中重写equals方法后:
<pre name="code" class="java">Student s1 = new Student(10);
Student s2 = new Student(10);
s1.equals(s2);//就为true

class Student {
	private int age;
	public Student(int age) {
		this.age = age;
	}
	//重写equals方法
	@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;
		return true;
	}
	
}
<span style="white-space:pre">		</span>Student s1 = new Student(10);<span style="white-space:pre">		</span>Student s2 = new Student(10);<span style="white-space:pre">		</span>Student s3 = s1;<span style="white-space:pre">		</span>System.out.println(s1.equals(s3));//true<span style="white-space:pre">		</span>System.out.println(s1.equals(s2));//<span style="color:#ff0000;">true</span><span style="white-space:pre">		</span>System.out.println(s1 == s2);//false

其它的一些方法:

A:hashCode() 返回对象的哈希值,根据哈希算法计算出来的一个值,这个值和地址值有关,但不是实际地址值。
B:getClass() 返回对象的字节码文件对象
C:finalize() 用于垃圾回收,在不确定的时间
D:clone() 可以实现对象的克隆,包括成员变量的数据复制,它是在堆内存新创建了一个一模一样的对象,但是要克隆的类必须实现该Cloneable接口:实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。 这个个接口是标记接口,没有方法,告诉我们实现该接口的类就可以实现对象的复制了。


Java之equals和==详解