使用和避免null
null可能作為默認(rèn)返回评疗,會(huì)導(dǎo)致歧義從而使程序丟失健壯性馍乙;
好的方面是递览,null有時(shí)是高效的拟淮。
Optional
Optional表示一個(gè)可能為 null 的 T 類型引用,它可能包含非null引用(此時(shí)為引用存在)监嗜,也可能什么也不包括(此時(shí)為引用缺失)谐檀,但它從來不會(huì)包括null值引用。
Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5
前置條件:Preconditions
方法調(diào)用的前置條件判斷更簡單裁奇。
Preconditions.checkArgument(i>j,"this is error message %s ",333);
相比 Apache Commons 提供的類似方法,我們把 Guava 中的 Preconditions 作為首選桐猬。Piotr Jagielski 在
他的博客中簡要地列舉了一些理由:
? 在靜態(tài)導(dǎo)入后,Guava 方法非常清楚明晰。checkNotNull 清楚地描述做了什么,會(huì)拋出什么異常;
? checkNotNull 直接返回檢查的參數(shù),讓你可以在構(gòu)造函數(shù)中保持字段的單行賦值風(fēng)格:this.field = check
NotNull(field)
? 簡單的刽肠、參數(shù)可變的 printf 風(fēng)格異常信息溃肪。鑒于這個(gè)優(yōu)點(diǎn),在 JDK7 已經(jīng)引入 Objects.requireNonNull 的
情況下,我們?nèi)匀唤ㄗh你使用 checkNotNull。
在編碼時(shí),如果某個(gè)值有多重的前置條件,我們建議你把它們放到不同的行,這樣有助于在調(diào)試時(shí)定位音五。此外,把每個(gè)前置條件放到不同的行,也可以幫助你編寫清晰和有用的錯(cuò)誤消息惫撰。
常見Object方法
equals
當(dāng)一個(gè)對象中的字段可以為 null 時(shí),實(shí)現(xiàn) Object.equals 方法會(huì)很痛苦,因?yàn)椴坏貌环謩e對它們進(jìn)行 null 檢查(否則直接調(diào)用equals方法會(huì)報(bào)出空異常)。使用 Objects.equal 幫助你執(zhí)行 null 敏感的 equals 判斷,從而避免拋出 NullPointerException躺涝。例如:
Objects.equal("a", "a"); // returns true
Objects.equal(null, "a"); // returns false
Objects.equal("a", null); // returns false
Objects.equal(null, null); // returns true
hashCode
用對象的所有字段作散列[hash]運(yùn)算應(yīng)當(dāng)更簡單厨钻。Guava 的 Objects.hashCode(Object...)會(huì)對傳入的字段序
列計(jì)算出合理的、順序敏感的散列值坚嗜。你可以使用 Objects.hashCode(field1, field2, ..., fieldn)來代替手動(dòng)計(jì)算
散列值夯膀。
toString
好的 toString 方法在調(diào)試時(shí)是無價(jià)之寶,但是編寫 toString 方法有時(shí)候卻很痛苦。使用 Objects.toStringHelper 可以輕松編寫有用的 toString 方法苍蔬。例如:
Objects.toStringHelper(this).add("x", 1).toString(); // Returns "ClassName{x=1}"
Objects.toStringHelper("MyObject").add("x", 1).toString(); // Returns "MyObject{x=1}"
compare / compareTo -> ComparisonChain
實(shí)現(xiàn)一個(gè)比較器[Comparator],或者直接實(shí)現(xiàn) Comparable 接口有時(shí)也傷不起诱建。考慮一下這種情況:
// 這部分代碼太瑣碎了,因此很容易搞亂,也很難調(diào)試
class Person implements Comparable<Person> {
private String lastName;
private String firstName;
private int zipCode;
public int compareTo(Person other) {
int cmp = lastName.compareTo(other.lastName);
if (cmp != 0) {
return cmp;
}
cmp = firstName.compareTo(other.firstName);
if (cmp != 0) {
return cmp;
}
return Integer.compare(zipCode, other.zipCode);
}
}
ComparisonChain 執(zhí)行一種懶比較:它執(zhí)行比較操作直至發(fā)現(xiàn)非零的結(jié)果,在那之后的比較輸入將被忽略碟绑。
public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(this.aString, that.aString)
.compare(this.anInt, that.anInt)
.compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
.result();
}