Class RecursiveToStringStyle

java.lang.Object
org.apache.commons.lang3.builder.ToStringStyle
org.apache.commons.lang3.builder.RecursiveToStringStyle
All Implemented Interfaces:
Serializable
Direct Known Subclasses:
MultilineRecursiveToStringStyle

Works with ToStringBuilder to create a "deep" toString.

To use this class write code as follows:

public class Job {
  String title;
  ...
}

public class Person {
  String name;
  int age;
  boolean smoker;
  Job job;

  ...

  public String toString() {
    return new ReflectionToStringBuilder(this, new RecursiveToStringStyle()).toString();
  }
}

This will produce a toString of the format: Person@7f54[name=Stephen,age=29,smoker=false,job=Job@43cd2[title=Manager]]

Graph safety: within one top-level toString() call, each object is rendered in detail at most once. A second (identity-equal) occurrence of an object (whether through a true cycle or through a shared (acyclic) reference) is rendered in the abbreviated Object.toString() format instead of being re-traversed. This keeps traversal cost linear in the size of the object graph; without it, shared references (reference "diamonds") would be re-traversed exponentially. An optional output-length limit can be set via RecursiveToStringStyle.Builder.setMaxOutputLength(int); once the produced string reaches the limit, further nested objects are replaced by a "...<truncated>" marker.

Since:
3.2
See Also:
  • Constructor Details

    • RecursiveToStringStyle

      Constructs a new instance with no output-length limit.
    • RecursiveToStringStyle

      public RecursiveToStringStyle(int maxOutputLength)
      Constructs a new instance with an output-length limit.
      Parameters:
      maxOutputLength - once the produced string reaches this length, further nested objects are replaced by a "...<truncated>" marker; 0 means unlimited.
      Since:
      3.21.0
  • Method Details

    • builder

    • accept

      protected boolean accept(Class<?> clazz)
      Tests whether or not to recursively format the given Class.

      By default, this method always filters out the following:

      Parameters:
      clazz - The class to test.
      Returns:
      Whether or not to recursively format instances of the given Class.
    • append

      public void append(StringBuffer buffer, String fieldName, Object[] array, Boolean fullDetail)
      Description copied from class: ToStringStyle
      Appends to the toString an Object array.
      Overrides:
      append in class ToStringStyle
      Parameters:
      buffer - The StringBuffer to populate.
      fieldName - The field name.
      array - The array to add to the toString.
      fullDetail - true for detail, false for summary info, null for style decides.
    • appendDetail

      protected void appendDetail(StringBuffer buffer, String fieldName, Collection<?> coll)
      Description copied from class: ToStringStyle
      Appends to the toString a Collection.
      Overrides:
      appendDetail in class ToStringStyle
      Parameters:
      buffer - The StringBuffer to populate.
      fieldName - The field name, typically not used as already appended.
      coll - The Collection to add to the toString, not null.
    • appendDetail

      public void appendDetail(StringBuffer buffer, String fieldName, Object value)
      Description copied from class: ToStringStyle
      Appends to the toString an Object value, printing the full detail of the Object.
      Overrides:
      appendDetail in class ToStringStyle
      Parameters:
      buffer - The StringBuffer to populate.
      fieldName - The field name, typically not used as already appended.
      value - The value to add to the toString, not null.
    • appendInternal

      protected void appendInternal(StringBuffer buffer, String fieldName, Object value, boolean detail)
      Appends to the toString an Object, correctly interpreting its type.

      This method performs the main lookup by Class type to correctly route arrays, Collections, Maps and Objects to the appropriate method.

      Either detail or summary views can be specified.

      If a cycle is detected, an object will be appended with the Object.toString() format.

      In addition to the cycle check performed by the superclass, this implementation shares a visited-object set across nested builders in the active traversal. The outer builder retains the set between appends and releases it on completion. Values that this style would traverse structurally (see accept(Class)) are rendered in detail at most once; later identity-equal occurrences are appended in the abbreviated Object.toString() format. This bounds the traversal to one visit per object, so shared (acyclic) references cannot cause exponential re-traversal. If an output-length limit was configured and the buffer has reached it, a "...<truncated>" marker is appended instead of the value.

      Overrides:
      appendInternal in class ToStringStyle
      Parameters:
      buffer - The StringBuffer to populate.
      fieldName - The field name, typically not used as already appended.
      value - The value to add to the toString, not null.
      detail - output detail or not.