直入正题
==
-
对于引用对象而言,比较两个对象引用的是否是同一个对象。比较是的两个引用对象的存储地址是否一样。
-
对于基本数据类型而言,比较的就是两个数据的值是否相等
String a = "123"; String b = "123"; String c = new String("123"); System.out.println(a==b); //true System.out.println(a==c); //false
分析
1. String a = "aaa"这种方式的时候java首先在内存中寻找"123"字符串,如果有,则让a指向“123“所在地址,否则创建一个字符串“123“; 2. String c = new String(“124”)这种方式,不管内存中是否存在字符串“123”,都会新开辟一块空间来存储字符串“123”,因此a==c结果为false
int a = 10; long b = 10L; double c = 10.0; System.out.println(a == b); // true System.out.println(a == c); // true System.out.println(b == c); // true
分析
代码所示,他们都指向地址为10的堆
equals()
-
equals用来比较的是两个对象的内容是否相等:如果两个对象的类型一致,并且内容一致,则返回true
-
由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象
-
若未对该方法进行覆盖重写,调用的仍然是Object类中的方法,返回的是==的判断
equals方法在所有类的基类Object中的定义,源码:
public boolean equals(Object obj) { return (this == obj); }
特殊定义
String X = "123";
- 该声明方式是java中唯一不需要new 就可以产生对象的途径
- 该形式赋值在java中叫直接量,是在常量池中而不是象new一样放在堆中
- 即当声明这样的一个字符串后,JVM会在常量池中先查找有有没有一个值为"123"的对象,如果有,就会把它赋给当前引用;如果没有,则在常量池中新创建一个"123"
- 只要值相等,任何多个引用都指向同一对象
hashCode()
hashCode()返回的是一个hashCode(hash码),hash码主要用于散列对象作为KEY来标示这个对象的存储位置,功能类似索引一样能够快速查找提取对象。
hashcode代表对象的地址说的是对象在hash表中的位置,物理地址说的对象存放在内存中的地址
默认情况下,Object中的hashCode() 返回对象的jvm地址
- 如果两个对象equals相等,那么这两个对象的HashCode一定也相同
- 如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置
重写equals()
有些时候仅仅是两个对象的某些属性相同就认为两个对象一样,这个时候我们一般要重写对象的equals()方法,重写的目的就是根据某些特定的属性来判断两个对象的是否相等。
在重写equals方法时,要注意满足以下特性:
- 自反性 :对任意引用值X,x.equals(x)的返回值一定为true
- 对称性: 对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true
- 传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true
- 一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变
- 非空性:任何非空的引用值X,x.equals(null)的返回值一定为false
重写hashCode()
一般情况下我们是不需要重写hashcode()的,Object.hashCode生成规则也有通用约定:
- 在一个应用程序,同一次执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改,那么,该对象调用多次hashCode方法,它必须始终如一地返回 同一个整数。同一个应用程序的多次执行过程中,这个整数可以不同,即这个应用程序这次执行返回的整数与下一次执行返回的整数可以不一致。
- 如果两个对象根据equals(Object)方法是相等的,那么这两个对象的hashCode方法必须返回的整数必须相等
- 如果两个对象根据equals(Object)方法是不相等的,那么调用这两个对象中任一个对象的hashCode方法,返回的整数有可能相等