旧时王谢堂前燕, 飞入寻常百姓家。 小编将带大家一块儿分析阿里巴巴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所映射的对象,致使内存泄漏。