做Java开发的常常要重写类的hashCode()和equals()。一般情况下,可以套常用的模板。Eclipse就套用这些模板,直接生成默认实现,可实现比较冗长,比如下面的例子
有类A,
1 2 3 4 5 6 7 8 9 |
public class A { private int a; private double b; private String c; } |
Eclipse的默认实现是这样的,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
public class A { private int a; private double b; private String c; @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + a; long temp; temp = Double.doubleToLongBits(b); result = prime * result + (int) (temp ^ (temp >>> 32)); result = prime * result + ((c == null) ? 0 : c.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; A other = (A) obj; if (a != other.a) return false; if (Double.doubleToLongBits(b) != Double.doubleToLongBits(other.b)) return false; if (c == null) { if (other.c != null) return false; } else if (!c.equals(other.c)) return false; return true; } } |
显然实现比较冗长,也比较乱,包含了很多细节,有些也不符合代码规范(比如if后没有花括号)。
用过Guava的同学都知道,使用Objects类可以大大简化这两个函数的实现。我试着扩展了Eclipse JDT,套用Guava的实现模板,那代码就漂亮多了。Guava隐藏了大量的实现细节。
如下,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class A { private int a; private double b; private String c; @Override public int hashCode() { return Objects.hashCode(a, b, c); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (!(obj instanceof A)) { return false; } A anotherInstance = (A) obj; return Objects.equal(anotherInstance.a, this.a) && Objects.equal(anotherInstance.b, this.b) && Objects.equal(anotherInstance.c, this.c); } } |
具体的代码实现在Github上,点这。
主要分如下有几步,
- Project Explorer的上下文菜单中加入新的功能选项。
- 通过Eclipse里事件得到Java CompliationUnit,使用ASTParser得到类里的Non-Static Member Field,然后就套用新模板吧。
- 一个源文件中可能包含多个Java Class,所以还要有个Dialog来选择在哪个类中实现方法 。
其他细节都在代码里的,有兴趣的就看看吧。😁