在org.apache.commons.lang.builder包中一共有7个类,用于帮助实现Java对象的一些基础的方法,如compareTo(), equals(), hashCode(), toString()等。他们分别是:
CompareToBuilder – 用于辅助实现Comparable.compareTo(Object)方法;
EqualsBuilder – 用于辅助实现Object.equals()方法;
HashCodeBuilder – 用于辅助实现Object.hashCode()方法;
ReflectionToStringBuilder – 使用反射机制辅助实现Object.toString()方法;
ToStringBuilder – 用于辅助实现Object.toString()方法;
StandardToStringStyle – 辅助ToStringBuilder控制标准格式;
ToStringStyle – 辅助ToStringBuilder控制输出格式。
import java.util.Date; import org.apache.commons.lang.builder.CompareToBuilder; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.apache.commons.lang.builder.StandardToStringStyle; public class BuilderTest { public static void main(String[] args) { Person person1 = new Person("郑致力", 32, new Date()); Person person2 = new Person("高婕", 27, new Date()); System.out.println("person1's info: " + person1); System.out.println("person2's info: " + person2); System.out.println("person1's hash code: " + person1.hashCode()); System.out.println("person2's hash code: " + person2.hashCode()); System.out.println("person1 equals person2? " + person1.equals(person2)); System.out.println("--------------More String Style of Object ------------------------------------"); System.out.println("person1's info: " + person1.toString2(ToStringStyle.MULTI_LINE_STYLE)); System.out.println("person1's info: " + person1.toString2(ToStringStyle.NO_FIELD_NAMES_STYLE)); System.out.println("person1's info: " + person1.toString2(ToStringStyle.SHORT_PREFIX_STYLE)); System.out.println("person1's info: " + person1.toString2(ToStringStyle.SIMPLE_STYLE)); System.out.println("person1's info: " + person1.toString2(new StandardToStringStyle())); } } class Person implements Comparable { private String name; private int age; private Date dateJoined; public Person() { }; public Person(String name, int age, Date dateJoined) { this.name = name; this.age = age; this.dateJoined = dateJoined; } public int compareTo(Object o) { if (!(o instanceof Person)) { return -1; } Person other = (Person) o; return new CompareToBuilder().append(name, other.getName()).append(age, other.getAge()).append(dateJoined, other.getDateJoined()) .toComparison(); } public boolean equals(Object o) { if (!(o instanceof Person)) { return false; } Person other = (Person) o; return new EqualsBuilder().append(name, other.getName()).append(age, other.getAge()).append(dateJoined, other.getDateJoined()) .isEquals(); } //注:两个equlas为true的对象在这里会被计算成不同的hash码,慎用 public int hashCode() { return new HashCodeBuilder().append(name).append(age) .append(dateJoined).toHashCode(); } public String toString() { return new ToStringBuilder(this).append("name", name) .append("age", age).append("dateJoined", dateJoined).toString(); } public String toString2(ToStringStyle style) { ToStringStyle _style = ToStringStyle.DEFAULT_STYLE; if (null != style) { _style = style; } return new ToStringBuilder(this, _style).append("name", name) .append("age", age).append("dateJoined", dateJoined).toString(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getDateJoined() { return dateJoined; } public void setDateJoined(Date dateJoined) { this.dateJoined = dateJoined; } }
这些builder用起来很简单,只要new一个实例,append需要参与的信息,然后加上toComparison、isEquals、toHashCode、toString结尾就可以了。如果不需要使用append指定信息,则可直接使用反射机制进行自动化实现,如下面的Student类:
class Student extends Person { private int grad; public Student() {super();} public Student(String name, int age, Date dateJoined, int grad) { super(name, age, dateJoined); this.grad = grad; } public int compareTo(Object o) { return CompareToBuilder.reflectionCompare(this, o); } public boolean equals(Object o) { return EqualsBuilder.reflectionEquals(this, o); } public int hashCode() { return HashCodeBuilder.reflectionHashCode(this); } public String toString() { return ReflectionToStringBuilder.toString(this); } }
这里需要补充一点,对于ToStringStyle类,代码中已经内置了5种,分别为ToStringStyle.DEFAULT_STYLE、ToStringStyle.MULTI_LINE_STYLE、ToStringStyle.NO_FIELD_NAMES_STYLE、ToStringStyle.SHORT_PREFIX_STYLE、ToStringStyle.SIMPLE_STYLE。不知道为什么,这5种内置类的实现都被定义成了private static final类了。所以如果上述5种类不能满足你的要求的话,想继承他们是不可能的。所以你需要创建StandardToStringStyle一个实例,然后调用它的方法来实现自定义的格式。在StandardToStringStyle的单元测试代码中,是这样调用的:
private static final StandardToStringStyle STYLE = new StandardToStringStyle(); static { STYLE.setUseShortClassName(true); STYLE.setUseIdentityHashCode(false); STYLE.setArrayStart("["); STYLE.setArraySeparator(", "); STYLE.setArrayEnd("]"); STYLE.setNullText("%NULL%"); STYLE.setSizeStartText("%SIZE="); STYLE.setSizeEndText("%"); STYLE.setSummaryObjectStartText("%"); STYLE.setSummaryObjectEndText("%"); }