序言:准备总结一些java基础的知识方便以后查阅,从equals入手
目录:
- 等于(==)详解
- equals方法详解
一、等于(==)详解
先明确一点:“==” 其实是存储地址的比较
1.在八大基本类型中‘==’
在基本类型,用“==”来比较两个变量存储的地址(变量存储的地址是其所指常量池中常量的地址),因常量地址和常量值一一对应,比较常量地址就是比较常量值,如下图:
结论:基本数据类型使用"=="可以判断两个变量(无论存储地址还是值)是否相等
2.引用类型对象中‘==’
在引用类型对象,用“==”来比较两个引用变量地址(引用变量存储的地址是其所指堆中对象的地址),每个对象地址不同,如下图:
结论:每一个对象都有自己的一块内存进行存储,所以每个对象地址都不一样。所以自定义类型使用"=="只能判断两个引用变量(地址)相等~是否为同一对象,无法判断两个对象(属性值)是否相等
3.特例:基本包装类型中‘==’
在基本包装类型(Integer、Short、Byte、Character、Long)有缓存-128<=int<=127,分情况:
1、Integer it = 127;这种直接赋值常量方式比较相等,因常量值-128<=int<=127在java栈中有缓存都指向同一个地址,所以==可以判断两个变量相等。如果it>127或者it<-128就无法比较变量相等
2、Integer it = new Integer(8);这种创建对象方式比较相等,因每个对象有一块内存地址存储,所以==无法判断两个对象属性值相等
二、equals方法详解
先明确两点:1、java对象的equals()方法都是继承Object.equals(Object o)方法的,该父类的equals方法其实就是使用了“==”。 2、equals其实无法在基本类型(int、char等)中比较使用,只能在基本包装类中使用(Integer、Character等)
1.在八大基本包装类型中equals()
在基本包装类型中,使用的equals()都重写了父类的equals()方法,先比较类型再比较值
//以Interger的equals方法为例
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
结论:基本包装类型可以使用equals()可以判断两个引用变量(属性值)是否相等
2、引用类型对象中equals()
一般引用类型如String都会重写equals()方法,来让equals()方法可以比较两个对象值是否相等。
public boolean equals(Object anObject) {
//使用“==”判断是否为同一个对象
if (this == anObject) {
return true;
}
//判断参数是否为String类型
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;
}
结论:引用类型重写equals()方法可以判断两个对象(属性值)是否相等,一般我们自定义的引用的类都会重写equals()和hashcode()方法。当然有例外:StringBuffer和StringBuilder就没有重写,无法判断其对象值是否相等。