ToStringBuilder 是 apache commons lang 库提供的实用程序类。
它提供了对数据的一致性和更好的控制,对象应该使用 toString() 方法以及以哪种格式公开。
它还可以通过消除在子类中覆盖 toString() 方法的需要来帮助消除代码大小。
它可用于构建某种设计模式以充分利用其提供的功能。
要在项目中包含 commons-lang,请在 maven 配置文件中添加以下依赖项。
<dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.5</version> </dependency>
为了演示 ToStringBuilder 在各种场景中构建 toString() 方法的各种可能用法,我借助了三个模型类,例如:AbstractUser.java、WebUser.java 和 GuestUser.java。
AbstractUser.java
package com.onitroad.model; import java.io.Serializable; import org.apache.commons.lang.builder.ToStringBuilder; import com.onitroad.style.CustomToStringStyle; public abstract class AbstractUser implements Serializable { private static final long serialVersionUID = 1L; private int id; private String firstName; private String lastName; private String age; //Setterss and getters }
WebUser.java
public class WebUser extends AbstractUser { private static final long serialVersionUID = 1L; private Date lastLoggedIn; public Date getLastLoggedIn() { return lastLoggedIn; } public void setLastLoggedIn(Date lastLoggedIn) { this.lastLoggedIn = lastLoggedIn; } }
GuestUser.java
public class GuestUser extends WebUser { private static final long serialVersionUID = 1L; private String location; public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } }
各种使用示例
- toString() 方法是最顶级的超类,被所有子类完美使用
我们可以在最顶层的超类中使用一次 Object 类的覆盖 toString() 方法,例如:在我们的例子中是 AbstractUser.java。
如果所有子类没有提供自己版本的 toString() 方法,则此方法将可供所有子类使用。
@Override public String toString() { return ToStringBuilder.reflectionToString(this); }
如果 toString() 在子类中未被覆盖,则上述方法能够为类及其子类提供所有可用信息。
package com.onitroad; import java.util.Date; import com.onitroad.model.GuestUser; import com.onitroad.model.WebUser; public class ToStringDemoUsage { public static void main(String[] args) { GuestUser guest = getGuestUser(); System.out.println(guest); } public static GuestUser getGuestUser() { GuestUser user = new GuestUser(); user.setId(100); user.setFirstName("Jamez"); user.setLastName("Gupta"); user.setAge("30"); user.setLastLoggedIn(new Date()); user.setLocation("New Amsterdam"); return user; } }
输出:
com.onitroad.model.GuestUser@d1f24bb[location=New Amsterdam,lastLoggedIn=Mon Jun 03 13:31:05 IST 2013,id=100,firstName=Jamez,lastName=Gupta,age=30]
- 任何字段类型的自定义格式,如日期
我们可以在 toString 方法中为任何字段类型强制执行自定义格式,这也与 toString() 实现不紧密耦合。
自定义格式化程序示例如下:
package com.onitroad.style; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.commons.lang.builder.ToStringStyle; public class CustomToStringStyle extends ToStringStyle { private static final long serialVersionUID = 1L; protected void appendDetail(StringBuffer buffer, String fieldName, Object value) { if (value instanceof Date) { value = new SimpleDateFormat("yyyy-MM-dd").format(value); } buffer.append(value); } }
要使用此格式化程序,请将其传递给这样的方法。
@Override public String toString() { return ToStringBuilder.reflectionToString(this, new CustomToStringStyle()); }
输出:
com.onitroad.model.GuestUser@7910769b[location=New Amsterdam,lastLoggedIn=2013-06-03,id=100,firstName=Jamez,lastName=Gupta,age=30]
- 通过简单的方法调用在子类中使用来自超类的信息
如果我们想覆盖子类中的 toString() 方法,并且我们想在向超类添加任何内容之前添加从超类检索到的信息,请这样做。
public class WebUser extends AbstractUser { //Other code @Override public String toString() { return new ToStringBuilder(this) .appendSuper(super.toString()) .append("lastLoggedIn", lastLoggedIn).toString(); } }
输出:
com.onitroad.model.GuestUser@22aed3a5[location=New Amsterdam,lastLoggedIn=2013-06-03,id=100,firstName=Jamez,lastName=Gupta,age=30,CustomMessage=I have been added additionally]
- 仅使用特定级别的继承层次结构的信息
假设在任何子类中我们确实需要公开所有超类的所有字段,我们也可以通过这种方式将信息包含到某个级别:
public class GuestUser extends WebUser { @Override public String toString() { return ToStringBuilder.reflectionToString(this,new CustomToStringStyle(),true,WebUser.class); } }
输出:
com.onitroad.model.GuestUser@18dd7404[location=New Amsterdam,lastLoggedIn=2013-06-03]
- 只包含你想要的信息
有时我们不想在 toString 方法中包含类中的所有字段。
好吧,你也有办法在这里做到这一点。
public abstract class AbstractUser implements Serializable { //Other code @Override public String toString() { return new ToStringBuilder(this) .append("firstName", firstName) .append("lastName", lastName) .append("age", age).toString(); } } public class GuestUser extends WebUser { //Other code @Override public String toString() { return new ToStringBuilder(this) .appendSuper(super.toString()) .append("location", location).toString(); } }
输出:
com.onitroad.model.GuestUser@6483dae1[firstName=Jamez,lastName=Gupta,age=30,location=New Amsterdam]