舊時王謝堂前燕, 飛入尋常百姓家。 小編將帶大家一塊兒分析阿里巴巴Java開發手冊!java
阿里巴巴Java開發手冊是阿里巴巴集團技術團隊的集體智慧結晶和經驗總結,以Java開發者爲中心視角,劃分爲編程規約、異常日誌、單元測試、安全規約、工程結構、MySQL數據庫六個維度。手冊的願景是碼出高效、碼出質量、效率優先、質量爲本。數據庫
之因此要寫這個系列的文章,首先是學習與總結,其次是思考與理解,更是分享與交流,手冊中的每一條每一項都有其背後隱藏的原理與經驗,咱們看到的只是冰山一角,深刻挖掘其背後的知識有益於更深入的理解,並在本身實際編程中提升本身的基本技術素養。編程
if (condition) {
...
return obj;
}
// 接着寫 else 的業務邏輯代碼;
複製代碼
說明:若是非得使用 if()...else if()...else...方式表達邏輯,【強制】避免後續代碼維 護困難,請勿超過 3 層。 正例:超過 3 層的 if-else 的邏輯判斷代碼可使用衛語句、策略模式、狀態模式等來實現, 其中衛語句示例以下:安全
public void today() {
if (isBusy()) {
System.out.println(「change time.」); return;
}
if (isFree()) {
System.out.println(「go to travel.」);
return;
}
System.out.println(「stay at home to learn Alibaba Java Coding Guidelines.」);
return;
}
複製代碼
咱們試圖經過例子來分析下上面的規則,在分析以前,咱們先明確在Java裏,默認的equals和hashCode方法的實現,以及把一個元素放入散列集合(HashSet、HashMap等)時,散列集合對equals和hashCode方法的斷定規則。 Java對象中默認的equals(Object obj)方法用來判斷兩個對象是否「相同」,若是「相同」則返回true,不然返回false。hashCode()方法返回一個int數,這個整數值是將該對象的內部地址轉換成一個整數返回的 。 在散列集合中存儲一個對象時,先進行hashCode的比較,若是hashCode不相等,則直接放入,不然繼續進行equals的比較,equals不相等才放入,equals相等就直接丟棄了。微信
package com.test;
import java.util.HashSet;
import java.util.Set;
public class OverrideEqualsTest {
public static void main(String[] args) {
Set<Point> set = new HashSet<Point>();
Point p1 = new Point(1, 1);
Point p2 = new Point(1, 1);
System.out.println("p1.equals(p2):" + p1.equals(p2));
set.add(p1);
set.add(p2);
set.add(p1);
System.out.println("set.size():" + set.size());
for (Point p : set) {
System.out.println(p);
}
}
static class Point {
private int x;
private int y;
public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Point other = (Point) obj;
if (x != other.x) {
return false;
}
if (y != other.y) {
return false;
}
return true;
}
@Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
}
}
複製代碼
運行結果: p1.equals(p2):true set.size():2 Point[x=1,y=1] Point[x=1,y=1]ide
分析:因爲沒有重寫hashCode方法,p1和p2對象默認的hashCode方法返回的兩個對象地址轉換的整數確定不一樣,因此p1和p2均可以放入set中,因此這並非咱們指望的結果。單元測試
package com.test;
import java.util.HashSet;
import java.util.Set;
public class OverrideHashCodeTest {
public static void main(String[] args) {
Set<Point> set = new HashSet<Point>();
Point p1 = new Point(1, 1);
Point p2 = new Point(1, 1);
System.out.println("p1.equals(p2):" + p1.equals(p2));
set.add(p1);
set.add(p2);
set.add(p1);
System.out.println("set.size():" + set.size());
for (Point p : set) {
System.out.println(p);
}
}
static class Point {
private int x;
private int y;
public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
final int prime = 3L;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
}
}
複製代碼
運行結果: p1.equals(p2):false set.size():2 Point[x=1,y=1] Point[x=1,y=1]學習
分析:因爲沒有重寫equals方法,p1和p2對象的默認的equals方法經過「==」來比較,而p1和p2是兩個不一樣的對象,因此p1和p2均可以放入set中,因此這也不是咱們指望的結果。 因此綜上,當咱們同時重寫equals和hashCode方法後,才能在散列集合操做中獲得一致性的結果。測試
package com.test;
public class Test {
public static void main(String[] args) {
Point p1 = new Point(1, 1);
Point p2 = new Point(2, 2);
set.add(p1);
set.add(p2);
System.out.println("set.size():" + set.size());
p2.setY(3);
set.remove(p1);
set.remove(p2);
System.out.println("set.size():" + set.size());
}
}
複製代碼
運行結果: set.size():2 set.size():1ui
分析:因爲在執行期間,修改了p2對象的y值,致使p2對象的hashCode返回值有變化,因此hashset的remove方法將找不到新的hashCode所映射的對象,致使內存泄漏。