ToStringBuilder无法打印嵌套对象的内容。

13

我目前正在使用Apache Commons API (commons-lang.jar)打印对象的值,如下所示:

ToStringBuilder.reflectionToString(object,ToStringStyle.MULTI_LINE_STYLE))
但是,如果该对象具有返回另一个对象的 Getter 方法,则此代码不会打印值。
例如,我有一个名为 Person 的对象,它有一个 Getter 方法,返回 Address 对象。使用上述代码,它只打印 Address 对象名称。我希望还能打印 Address 对象的值,如果我将 person.getAddress() 传递给上面的代码,则可以打印出来,但我想在传递 person 对象时看到所有内容。
您有什么建议吗?
4个回答

9

这是因为它不会递归生成toString方法。你可以寻找其他工具,或者自己实现(最好是使用IDE自动生成)所有类的Object#toString()方法。

例如:

public class Person {
    private String name;
    private Address address;
    // Add/generate ctors, getters and setters.

    public String toString() {
        return String.format("Person[name: %s, %s]", name, address);
    }
}

并且

public class Address {
    private String street;
    private String city;
    // Add/generate ctors, getters and setters.

    public String toString() {
        return String.format("Address[street: %s, city: %s]", street, city);
    }
}

这样做可以实现以下目的:
String personString = person.toString();

并且

System.out.println(person);

会产生类似以下的结果。
Person[name: goutham, Address[street: Main Street 1, city: New York]]

9
自从Apache Commons Lang 3.2版本起,您可以使用RecursiveToStringStyle来实现您想要的精确控制。
两种可选方式:
ToStringBuilder.reflectionToString(object, new RecursiveToStringStyle());

或者
ToStringBuilder.reflectionToString(object, new MultilineRecursiveToStringStyle());

MultilineRecursiveToStringStyle 可用于版本3.4及以上版本。


5
你可以使用这种方法来转储每个对象。
 public static String dump(Object object) {
    Field[] fields = object.getClass().getDeclaredFields();
    StringBuilder sb = new StringBuilder();
    sb.append(object.getClass().getSimpleName()).append('{');

    boolean firstRound = true;

    for (Field field : fields) {
        if (!firstRound) {
            sb.append(", ");
        }
        firstRound = false;
        field.setAccessible(true);
        try {
            final Object fieldObj = field.get(object);
            final String value;
            if (null == fieldObj) {
                value = "null";
            } else {
                value = fieldObj.toString();
            }
            sb.append(field.getName()).append('=').append('\'')
                    .append(value).append('\'');
        } catch (IllegalAccessException ignore) {
            //this should never happen
        }

    }

    sb.append('}');
    return sb.toString();
}

如果对象内部有对象,则将obj1.obj2作为参数传递。

3
你可以为所有类定义一个基类,该基类将按以下方式定义toString方法:
public abstract class MyBaseClass{
  public String toString(){
    return ToStringBuilder.reflectionToString(object,ToStringStyle.MULTI_LINE_STYLE));
  }
}

然后只需使您的类扩展它。 这种方法可以使您的所有领域对象都能够生成一个漂亮的 toString()。


2
我给你点了个踩。Java类只能继承一个对象,为了使打印变得更容易而这样做,在我看来是不道德的。 - Duncan Jones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接