在我們的實(shí)際開(kāi)發(fā)中,通常會(huì)認(rèn)為兩個(gè)對(duì)象的內(nèi)容相等時(shí),則兩個(gè)對(duì)象相等,equals返回true。對(duì)象內(nèi)容不同,則返回false。
可以總結(jié)為兩種情況:
1、類未復(fù)寫equals方法,則使用equals方法比較兩個(gè)對(duì)象時(shí),相當(dāng)于==比較,即兩個(gè)對(duì)象的地址是否相等。地址相等,返回true,地址不相等,返回false。
2、類復(fù)寫equals方法,比較兩個(gè)對(duì)象時(shí),則走復(fù)寫之后的判斷方式。通常,我們會(huì)將equals復(fù)寫成:當(dāng)兩個(gè)對(duì)象內(nèi)容相同時(shí),則equals返回true,內(nèi)容不同時(shí),返回false。
注意:用“==”比較的是引用的地址,用equals比較的就是值。Object類中的equals方法定義為判斷兩個(gè)對(duì)象的地址是否相等(可以理解成是否是同一個(gè)對(duì)象),地址相等則認(rèn)為是對(duì)象相等。這也就意味著,我們新建的所有類如果沒(méi)有復(fù)寫equals方法,那么判斷兩個(gè)對(duì)象是否相等時(shí)就等同于“==”,也就是兩個(gè)對(duì)象的地址是否相等。
問(wèn)題:
1、假設(shè)對(duì)象的屬性不定,那重寫equals時(shí)肯定無(wú)法窮盡所以字段;
2、對(duì)象是第三方的引用,無(wú)法重寫equals方法;
解決方式:
equals方法中使用反射獲取所有字段的name和value,逐個(gè)對(duì)比;無(wú)法重寫equal方法,就自己隨便寫一個(gè),將要對(duì)比的對(duì)象作為入?yún)G進(jìn)去;
參考代碼1:比較
public StringBuilder compareContract(CreateContractSignInfoRequest sign, CreateContractSignInfoRequest existSign) {
StringBuilder stringBuilder = new StringBuilder();
try {
Field[] fields = getAllFields(sign);
for (int j = 0; j < fields.length; j++) {
fields[j].setAccessible(true);
// 字段值
if (!fields[j].get(sign).equals(fields[j].get(existSign))) {
stringBuilder.append(existSign.getUserName());
stringBuilder.append(fields[j].getName() + "、");
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return stringBuilder;
}
參考代碼2:獲取所有屬性
/**
* 獲取所有屬性,包括父類
*
* @param object
* @return
*/
public Field[] getAllFields(Object object) {
Class clazz = object.getClass();
List<Field> fieldList = new ArrayList<>();
while (clazz != null) {
fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
clazz = clazz.getSuperclass();
}
Field[] fields = new Field[fieldList.size()];
fieldList.toArray(fields);
return fields;
}
反射擴(kuò)展:
(1)獲取對(duì)象所屬類的Class方法。
Class c = Class.forName("包.類名稱");
(2)獲得該類的所有Filed(不包括父類)。
Field[] fields = c.getDeclaredFields();
(3)將所有屬性的訪問(wèn)權(quán)限設(shè)為true。
因?yàn)镴avaBean中所有的屬性訪問(wèn)權(quán)限都是private,所以無(wú)法直接獲得所有屬性,因此我們必須獲得其訪問(wèn)權(quán)限,通過(guò)下面的方法完成:
setAccessible(true);
(4)輸出對(duì)象屬性
f.getField(對(duì)象名稱);
(5)獲取字段名
fields[j].getName()
(6)獲取字段值
fields[j].get(obj)