Objects類是一個提供對象基礎(chǔ)操作的工具類,其提供的方法包括null-safe或tolerant-safe的對象hashcode計算力麸,toString和比較等挚冤。
所在路徑:\java\util\Objects.java
一减噪、構(gòu)造器
Objects類被final修飾致扯,不能被繼承。其構(gòu)造方法直接拋出一個Error像街,不允許被實例化黎棠。
private Objects() {
throw new AssertionError("No java.util.Objects instances for you!");
}
二、equals()
在判斷值相等時可以容忍對象為null的情況镰绎。
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
相比之下脓斩,Object類的equals()方法在自身為null時會拋出nullPointerException。
Object類的equals()方法:
public boolean equals(Object obj) {
return (this == obj);
}
三跟狱、deepEquals()
deepEquals()方法實現(xiàn)了兩個對象是否相等的深度判斷俭厚,如果對象是一個數(shù)組,則對數(shù)組的每一個元素進行比較驶臊;如果數(shù)組中的每一個元素仍然是object挪挤,則對其進行遞歸的比較。
被比較的任意一個對象為null時返回false而不是繼續(xù)判斷关翎,因此在兩對象都為null時只能得到false而不是true扛门。
public static boolean deepEquals(Object a, Object b) {
if (a == b)
return true;
else if (a == null || b == null)
return false;
else
return Arrays.deepEquals0(a, b);
}
Arrays.deepEquals0()方法的源碼為:
static boolean deepEquals0(Object e1, Object e2) {
assert e1 != null;
boolean eq;
if (e1 instanceof Object[] && e2 instanceof Object[])
eq = deepEquals ((Object[]) e1, (Object[]) e2);
else if (e1 instanceof byte[] && e2 instanceof byte[])
eq = equals((byte[]) e1, (byte[]) e2);
else if (e1 instanceof short[] && e2 instanceof short[])
eq = equals((short[]) e1, (short[]) e2);
else if (e1 instanceof int[] && e2 instanceof int[])
eq = equals((int[]) e1, (int[]) e2);
else if (e1 instanceof long[] && e2 instanceof long[])
eq = equals((long[]) e1, (long[]) e2);
else if (e1 instanceof char[] && e2 instanceof char[])
eq = equals((char[]) e1, (char[]) e2);
else if (e1 instanceof float[] && e2 instanceof float[])
eq = equals((float[]) e1, (float[]) e2);
else if (e1 instanceof double[] && e2 instanceof double[])
eq = equals((double[]) e1, (double[]) e2);
else if (e1 instanceof boolean[] && e2 instanceof boolean[])
eq = equals((boolean[]) e1, (boolean[]) e2);
else
eq = e1.equals(e2);
return eq;
}
Tips:
1、assert <boolean表達式>:如果<boolean表達式>為true纵寝,則程序繼續(xù)執(zhí)行论寨。如果為false,則程序拋出AssertionError爽茴,并終止執(zhí)行葬凳。
2、assert <boolean表達式> : <錯誤信息表達式>:如果<boolean表達式>為true室奏,則程序繼續(xù)執(zhí)行火焰。如果為false,則程序拋出java.lang.AssertionError胧沫,并輸入<錯誤信息表達式>昌简。
deepEquals()方法的源碼為:
public static boolean deepEquals(Object[] a1, Object[] a2) {
if (a1 == a2)
return true;
if (a1 == null || a2==null)
return false;
int length = a1.length;
if (a2.length != length)
return false;
for (int i = 0; i < length; i++) {
Object e1 = a1[i];
Object e2 = a2[i];
if (e1 == e2)
continue;
if (e1 == null)
return false;
// Figure out whether the two elements are equal
boolean eq = deepEquals0(e1, e2);
if (!eq)
return false;
}
return true;
}
四、hashcode()
對象為null時返回0绒怨,否則調(diào)用Object類的hashcode方法纯赎。
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
Object類的hashcode()方法源碼為:
public native int hashCode();
五、hash()
為輸入序列生成hashcode南蹂。此方法返回任意Object序列的hashcode犬金,如果序列過長,int會溢出成負數(shù)六剥,但仍然是唯一的佑附。
public static int hash(Object... values) {
return Arrays.hashCode(values);
}
其中Arrays.hashcode()方法的源碼為:
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
六、toString()
將toString()方法重寫成了如下形式仗考,但最終調(diào)用的還是Object類的toString()方法音同。方法包裝的意義在于支持null值,如果入?yún)閚ull則返回字符串"null"秃嗜。
public static String toString(Object o) {
return String.valueOf(o);
}
public static String toString(Object o, String nullDefault) {
return (o != null) ? o.toString() : nullDefault;
}
String.valueOf()方法的源碼為:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Object類的toString()方法源碼為:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
七权均、compare()
將普通的compare過程包裝了一下。
public static <T> int compare(T a, T b, Comparator<? super T> c) {
return (a == b) ? 0 : c.compare(a, b);
}
八锅锨、requireNonNull()
優(yōu)雅地判空并在對象為空時拋錯叽赊。
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
public static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
}
public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
if (obj == null)
throw new NullPointerException(messageSupplier.get());
return obj;
}
Supplier是一個接口,可以理解為對象提供者必搞。他是一個函數(shù)式編程接口必指,只有一個get()方法。當程序需要一個對象時恕洲,可以通過get()方法來獲取。下面是一個使用示例:
public void test(){
// 創(chuàng)建Supplier容器,聲明為TestSupplier類型常拓,此時并不會調(diào)用對象的構(gòu)造方法谐檀,即不會創(chuàng)建對象
Supplier<RobotUser> user = new RobotUser();
// 調(diào)用get()方法,此時會調(diào)用對象的構(gòu)造方法,即獲得到真正對象
RobotUser user1 = user.get();
}
// 當使用此方法實現(xiàn)get方法時,每次返回的對象都不同
public RobotUser get() {
return new RobotUser();
}
// 當使用此方法實現(xiàn)get方法時,每次返回的對象都相同
RobotUser user = new RobotUser();
public RobotUser get() {
return user;
}
九底燎、isNull()
優(yōu)雅地判空并返回結(jié)果。
public static boolean isNull(Object obj) {
return obj == null;
}
十弹砚、nonNull()
優(yōu)雅地判定非空并返回結(jié)果双仍,與isNull()方法相反。
public static boolean nonNull(Object obj) {
return obj != null;
}