ReflectionToStringBuilder.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.apache.commons.lang3.builder;

  18. import java.lang.reflect.AccessibleObject;
  19. import java.lang.reflect.Field;
  20. import java.lang.reflect.Modifier;
  21. import java.util.Arrays;
  22. import java.util.Collection;
  23. import java.util.Comparator;
  24. import java.util.Objects;

  25. import org.apache.commons.lang3.ArraySorter;
  26. import org.apache.commons.lang3.ArrayUtils;
  27. import org.apache.commons.lang3.ClassUtils;
  28. import org.apache.commons.lang3.stream.Streams;

  29. /**
  30.  * Assists in implementing {@link Object#toString()} methods using reflection.
  31.  *
  32.  * <p>
  33.  * This class uses reflection to determine the fields to append. Because these fields are usually private, the class
  34.  * uses {@link java.lang.reflect.AccessibleObject#setAccessible(java.lang.reflect.AccessibleObject[], boolean)} to
  35.  * change the visibility of the fields. This will fail under a security manager, unless the appropriate permissions are
  36.  * set up correctly.
  37.  * </p>
  38.  * <p>
  39.  * Using reflection to access (private) fields circumvents any synchronization protection guarding access to these
  40.  * fields. If a toString method cannot safely read a field, you should exclude it from the toString method, or use
  41.  * synchronization consistent with the class' lock management around the invocation of the method. Take special care to
  42.  * exclude non-thread-safe collection classes, because these classes may throw ConcurrentModificationException if
  43.  * modified while the toString method is executing.
  44.  * </p>
  45.  * <p>
  46.  * A typical invocation for this method would look like:
  47.  * </p>
  48.  * <pre>
  49.  * public String toString() {
  50.  *     return ReflectionToStringBuilder.toString(this);
  51.  * }
  52.  * </pre>
  53.  * <p>
  54.  * You can also use the builder to debug 3rd party objects:
  55.  * </p>
  56.  * <pre>
  57.  * System.out.println(&quot;An object: &quot; + ReflectionToStringBuilder.toString(anObject));
  58.  * </pre>
  59.  * <p>
  60.  * A subclass can control field output by overriding the methods:
  61.  * </p>
  62.  * <ul>
  63.  * <li>{@link #accept(java.lang.reflect.Field)}</li>
  64.  * <li>{@link #getValue(java.lang.reflect.Field)}</li>
  65.  * </ul>
  66.  * <p>
  67.  * For example, this method does <em>not</em> include the {@code password} field in the returned {@link String}:
  68.  * </p>
  69.  * <pre>
  70.  * public String toString() {
  71.  *     return (new ReflectionToStringBuilder(this) {
  72.  *         protected boolean accept(Field f) {
  73.  *             return super.accept(f) &amp;&amp; !f.getName().equals(&quot;password&quot;);
  74.  *         }
  75.  *     }).toString();
  76.  * }
  77.  * </pre>
  78.  * <p>
  79.  * Alternatively the {@link ToStringExclude} annotation can be used to exclude fields from being incorporated in the
  80.  * result.
  81.  * </p>
  82.  * <p>
  83.  * It is also possible to use the {@link ToStringSummary} annotation to output the summary information instead of the
  84.  * detailed information of a field.
  85.  * </p>
  86.  * <p>
  87.  * The exact format of the {@code toString} is determined by the {@link ToStringStyle} passed into the constructor.
  88.  * </p>
  89.  *
  90.  * <p>
  91.  * <b>Note:</b> the default {@link ToStringStyle} will only do a "shallow" formatting, i.e. composed objects are not
  92.  * further traversed. To get "deep" formatting, use an instance of {@link RecursiveToStringStyle}.
  93.  * </p>
  94.  *
  95.  * @since 2.0
  96.  */
  97. public class ReflectionToStringBuilder extends ToStringBuilder {

  98.     /**
  99.      * Converts the given Collection into an array of Strings. The returned array does not contain {@code null}
  100.      * entries. Note that {@link Arrays#sort(Object[])} will throw an {@link NullPointerException} if an array element
  101.      * is {@code null}.
  102.      *
  103.      * @param collection
  104.      *            The collection to convert
  105.      * @return A new array of Strings.
  106.      */
  107.     static String[] toNoNullStringArray(final Collection<String> collection) {
  108.         if (collection == null) {
  109.             return ArrayUtils.EMPTY_STRING_ARRAY;
  110.         }
  111.         return toNoNullStringArray(collection.toArray());
  112.     }

  113.     /**
  114.      * Returns a new array of Strings without null elements. Internal method used to normalize exclude lists
  115.      * (arrays and collections). Note that {@link Arrays#sort(Object[])} will throw an {@link NullPointerException}
  116.      * if an array element is {@code null}.
  117.      *
  118.      * @param array
  119.      *            The array to check
  120.      * @return The given array or a new array without null.
  121.      */
  122.     static String[] toNoNullStringArray(final Object[] array) {
  123.         return Streams.nonNull(array).map(Objects::toString).toArray(String[]::new);
  124.     }

  125.     /**
  126.      * Builds a {@code toString} value using the default {@link ToStringStyle} through reflection.
  127.      *
  128.      * <p>
  129.      * It uses {@code AccessibleObject.setAccessible} to gain access to private fields. This means that it will
  130.      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
  131.      * also not as efficient as testing explicitly.
  132.      * </p>
  133.      *
  134.      * <p>
  135.      * Transient members will be not be included, as they are likely derived. Static fields will not be included.
  136.      * Superclass fields will be appended.
  137.      * </p>
  138.      *
  139.      * @param object
  140.      *            the Object to be output
  141.      * @return the String result
  142.      * @throws IllegalArgumentException
  143.      *             if the Object is {@code null}
  144.      *
  145.      * @see ToStringExclude
  146.      * @see ToStringSummary
  147.      */
  148.     public static String toString(final Object object) {
  149.         return toString(object, null, false, false, null);
  150.     }

  151.     /**
  152.      * Builds a {@code toString} value through reflection.
  153.      *
  154.      * <p>
  155.      * It uses {@code AccessibleObject.setAccessible} to gain access to private fields. This means that it will
  156.      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
  157.      * also not as efficient as testing explicitly.
  158.      * </p>
  159.      *
  160.      * <p>
  161.      * Transient members will be not be included, as they are likely derived. Static fields will not be included.
  162.      * Superclass fields will be appended.
  163.      * </p>
  164.      *
  165.      * <p>
  166.      * If the style is {@code null}, the default {@link ToStringStyle} is used.
  167.      * </p>
  168.      *
  169.      * @param object
  170.      *            the Object to be output
  171.      * @param style
  172.      *            the style of the {@code toString} to create, may be {@code null}
  173.      * @return the String result
  174.      * @throws IllegalArgumentException
  175.      *             if the Object or {@link ToStringStyle} is {@code null}
  176.      *
  177.      * @see ToStringExclude
  178.      * @see ToStringSummary
  179.      */
  180.     public static String toString(final Object object, final ToStringStyle style) {
  181.         return toString(object, style, false, false, null);
  182.     }

  183.     /**
  184.      * Builds a {@code toString} value through reflection.
  185.      *
  186.      * <p>
  187.      * It uses {@code AccessibleObject.setAccessible} to gain access to private fields. This means that it will
  188.      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
  189.      * also not as efficient as testing explicitly.
  190.      * </p>
  191.      *
  192.      * <p>
  193.      * If the {@code outputTransients} is {@code true}, transient members will be output, otherwise they
  194.      * are ignored, as they are likely derived fields, and not part of the value of the Object.
  195.      * </p>
  196.      *
  197.      * <p>
  198.      * Static fields will not be included. Superclass fields will be appended.
  199.      * </p>
  200.      *
  201.      * <p>
  202.      * If the style is {@code null}, the default {@link ToStringStyle} is used.
  203.      * </p>
  204.      *
  205.      * @param object
  206.      *            the Object to be output
  207.      * @param style
  208.      *            the style of the {@code toString} to create, may be {@code null}
  209.      * @param outputTransients
  210.      *            whether to include transient fields
  211.      * @return the String result
  212.      * @throws IllegalArgumentException
  213.      *             if the Object is {@code null}
  214.      *
  215.      * @see ToStringExclude
  216.      * @see ToStringSummary
  217.      */
  218.     public static String toString(final Object object, final ToStringStyle style, final boolean outputTransients) {
  219.         return toString(object, style, outputTransients, false, null);
  220.     }

  221.     /**
  222.      * Builds a {@code toString} value through reflection.
  223.      *
  224.      * <p>
  225.      * It uses {@code AccessibleObject.setAccessible} to gain access to private fields. This means that it will
  226.      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
  227.      * also not as efficient as testing explicitly.
  228.      * </p>
  229.      *
  230.      * <p>
  231.      * If the {@code outputTransients} is {@code true}, transient fields will be output, otherwise they
  232.      * are ignored, as they are likely derived fields, and not part of the value of the Object.
  233.      * </p>
  234.      *
  235.      * <p>
  236.      * If the {@code outputStatics} is {@code true}, static fields will be output, otherwise they are
  237.      * ignored.
  238.      * </p>
  239.      *
  240.      * <p>
  241.      * Static fields will not be included. Superclass fields will be appended.
  242.      * </p>
  243.      *
  244.      * <p>
  245.      * If the style is {@code null}, the default {@link ToStringStyle} is used.
  246.      * </p>
  247.      *
  248.      * @param object
  249.      *            the Object to be output
  250.      * @param style
  251.      *            the style of the {@code toString} to create, may be {@code null}
  252.      * @param outputTransients
  253.      *            whether to include transient fields
  254.      * @param outputStatics
  255.      *            whether to include static fields
  256.      * @return the String result
  257.      * @throws IllegalArgumentException
  258.      *             if the Object is {@code null}
  259.      *
  260.      * @see ToStringExclude
  261.      * @see ToStringSummary
  262.      * @since 2.1
  263.      */
  264.     public static String toString(final Object object, final ToStringStyle style, final boolean outputTransients, final boolean outputStatics) {
  265.         return toString(object, style, outputTransients, outputStatics, null);
  266.     }

  267.     /**
  268.      * Builds a {@code toString} value through reflection.
  269.      *
  270.      * <p>
  271.      * It uses {@code AccessibleObject.setAccessible} to gain access to private fields. This means that it will
  272.      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
  273.      * also not as efficient as testing explicitly.
  274.      * </p>
  275.      *
  276.      * <p>
  277.      * If the {@code outputTransients} is {@code true}, transient fields will be output, otherwise they
  278.      * are ignored, as they are likely derived fields, and not part of the value of the Object.
  279.      * </p>
  280.      *
  281.      * <p>
  282.      * If the {@code outputStatics} is {@code true}, static fields will be output, otherwise they are
  283.      * ignored.
  284.      * </p>
  285.      *
  286.      * <p>
  287.      * Superclass fields will be appended up to and including the specified superclass. A null superclass is treated as
  288.      * {@link Object}.
  289.      * </p>
  290.      *
  291.      * <p>
  292.      * If the style is {@code null}, the default {@link ToStringStyle} is used.
  293.      * </p>
  294.      *
  295.      * @param <T>
  296.      *            the type of the object
  297.      * @param object
  298.      *            the Object to be output
  299.      * @param style
  300.      *            the style of the {@code toString} to create, may be {@code null}
  301.      * @param outputTransients
  302.      *            whether to include transient fields
  303.      * @param outputStatics
  304.      *            whether to include static fields
  305.      * @param excludeNullValues
  306.      *            whether to exclude fields whose values are null
  307.      * @param reflectUpToClass
  308.      *            the superclass to reflect up to (inclusive), may be {@code null}
  309.      * @return the String result
  310.      * @throws IllegalArgumentException
  311.      *             if the Object is {@code null}
  312.      *
  313.      * @see ToStringExclude
  314.      * @see ToStringSummary
  315.      * @since 3.6
  316.      */
  317.     public static <T> String toString(
  318.             final T object, final ToStringStyle style, final boolean outputTransients,
  319.             final boolean outputStatics, final boolean excludeNullValues, final Class<? super T> reflectUpToClass) {
  320.         return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics, excludeNullValues)
  321.                 .toString();
  322.     }

  323.     /**
  324.      * Builds a {@code toString} value through reflection.
  325.      *
  326.      * <p>
  327.      * It uses {@code AccessibleObject.setAccessible} to gain access to private fields. This means that it will
  328.      * throw a security exception if run under a security manager, if the permissions are not set up correctly. It is
  329.      * also not as efficient as testing explicitly.
  330.      * </p>
  331.      *
  332.      * <p>
  333.      * If the {@code outputTransients} is {@code true}, transient fields will be output, otherwise they
  334.      * are ignored, as they are likely derived fields, and not part of the value of the Object.
  335.      * </p>
  336.      *
  337.      * <p>
  338.      * If the {@code outputStatics} is {@code true}, static fields will be output, otherwise they are
  339.      * ignored.
  340.      * </p>
  341.      *
  342.      * <p>
  343.      * Superclass fields will be appended up to and including the specified superclass. A null superclass is treated as
  344.      * {@link Object}.
  345.      * </p>
  346.      *
  347.      * <p>
  348.      * If the style is {@code null}, the default {@link ToStringStyle} is used.
  349.      * </p>
  350.      *
  351.      * @param <T>
  352.      *            the type of the object
  353.      * @param object
  354.      *            the Object to be output
  355.      * @param style
  356.      *            the style of the {@code toString} to create, may be {@code null}
  357.      * @param outputTransients
  358.      *            whether to include transient fields
  359.      * @param outputStatics
  360.      *            whether to include static fields
  361.      * @param reflectUpToClass
  362.      *            the superclass to reflect up to (inclusive), may be {@code null}
  363.      * @return the String result
  364.      * @throws IllegalArgumentException
  365.      *             if the Object is {@code null}
  366.      *
  367.      * @see ToStringExclude
  368.      * @see ToStringSummary
  369.      * @since 2.1
  370.      */
  371.     public static <T> String toString(
  372.             final T object, final ToStringStyle style, final boolean outputTransients,
  373.             final boolean outputStatics, final Class<? super T> reflectUpToClass) {
  374.         return new ReflectionToStringBuilder(object, style, null, reflectUpToClass, outputTransients, outputStatics)
  375.                 .toString();
  376.     }

  377.     /**
  378.      * Builds a String for a toString method excluding the given field names.
  379.      *
  380.      * @param object
  381.      *            The object to "toString".
  382.      * @param excludeFieldNames
  383.      *            The field names to exclude. Null excludes nothing.
  384.      * @return The toString value.
  385.      */
  386.     public static String toStringExclude(final Object object, final Collection<String> excludeFieldNames) {
  387.         return toStringExclude(object, toNoNullStringArray(excludeFieldNames));
  388.     }

  389.     /**
  390.      * Builds a String for a toString method excluding the given field names.
  391.      *
  392.      * @param object
  393.      *            The object to "toString".
  394.      * @param excludeFieldNames
  395.      *            The field names to exclude
  396.      * @return The toString value.
  397.      */
  398.     public static String toStringExclude(final Object object, final String... excludeFieldNames) {
  399.         return new ReflectionToStringBuilder(object).setExcludeFieldNames(excludeFieldNames).toString();
  400.     }

  401.     /**
  402.      * Builds a String for a toString method including the given field names.
  403.      *
  404.      * @param object
  405.      *            The object to "toString".
  406.      * @param includeFieldNames
  407.      *            {@code null} or empty means all fields are included. All fields are included by default. This method will override the default behavior.
  408.      * @return The toString value.
  409.      * @since 3.13.0
  410.      */
  411.     public static String toStringInclude(final Object object, final Collection<String> includeFieldNames) {
  412.         return toStringInclude(object, toNoNullStringArray(includeFieldNames));
  413.     }

  414.     /**
  415.      * Builds a String for a toString method including the given field names.
  416.      *
  417.      * @param object
  418.      *            The object to "toString".
  419.      * @param includeFieldNames
  420.      *            The field names to include. {@code null} or empty means all fields are included. All fields are included by default. This method will override the default
  421.      *             behavior.
  422.      * @return The toString value.
  423.      * @since 3.13.0
  424.      */
  425.     public static String toStringInclude(final Object object, final String... includeFieldNames) {
  426.         return new ReflectionToStringBuilder(object).setIncludeFieldNames(includeFieldNames).toString();
  427.     }

  428.     /**
  429.      * Whether or not to append static fields.
  430.      */
  431.     private boolean appendStatics;

  432.     /**
  433.      * Whether or not to append transient fields.
  434.      */
  435.     private boolean appendTransients;

  436.     /**
  437.      * Whether or not to append fields that are null.
  438.      */
  439.     private boolean excludeNullValues;

  440.     /**
  441.      * Which field names to exclude from output. Intended for fields like {@code "password"}.
  442.      *
  443.      * @since 3.0 this is protected instead of private
  444.      */
  445.     protected String[] excludeFieldNames;

  446.     /**
  447.      * Field names that will be included in the output. All fields are included by default.
  448.      *
  449.      * @since 3.13.0
  450.      */
  451.     protected String[] includeFieldNames;

  452.     /**
  453.      * The last super class to stop appending fields for.
  454.      */
  455.     private Class<?> upToClass;

  456.     /**
  457.      * Constructs a new instance.
  458.      *
  459.      * <p>
  460.      * This constructor outputs using the default style set with {@code setDefaultStyle}.
  461.      * </p>
  462.      *
  463.      * @param object
  464.      *            the Object to build a {@code toString} for, must not be {@code null}
  465.      */
  466.     public ReflectionToStringBuilder(final Object object) {
  467.         super(object);
  468.     }

  469.     /**
  470.      * Constructs a new instance.
  471.      *
  472.      * <p>
  473.      * If the style is {@code null}, the default style is used.
  474.      * </p>
  475.      *
  476.      * @param object
  477.      *            the Object to build a {@code toString} for, must not be {@code null}
  478.      * @param style
  479.      *            the style of the {@code toString} to create, may be {@code null}
  480.      */
  481.     public ReflectionToStringBuilder(final Object object, final ToStringStyle style) {
  482.         super(object, style);
  483.     }

  484.     /**
  485.      * Constructs a new instance.
  486.      *
  487.      * <p>
  488.      * If the style is {@code null}, the default style is used.
  489.      * </p>
  490.      *
  491.      * <p>
  492.      * If the buffer is {@code null}, a new one is created.
  493.      * </p>
  494.      *
  495.      * @param object
  496.      *            the Object to build a {@code toString} for
  497.      * @param style
  498.      *            the style of the {@code toString} to create, may be {@code null}
  499.      * @param buffer
  500.      *            the {@link StringBuffer} to populate, may be {@code null}
  501.      */
  502.     public ReflectionToStringBuilder(final Object object, final ToStringStyle style, final StringBuffer buffer) {
  503.         super(object, style, buffer);
  504.     }

  505.     /**
  506.      * Constructs a new instance.
  507.      *
  508.      * @param <T>
  509.      *            the type of the object
  510.      * @param object
  511.      *            the Object to build a {@code toString} for
  512.      * @param style
  513.      *            the style of the {@code toString} to create, may be {@code null}
  514.      * @param buffer
  515.      *            the {@link StringBuffer} to populate, may be {@code null}
  516.      * @param reflectUpToClass
  517.      *            the superclass to reflect up to (inclusive), may be {@code null}
  518.      * @param outputTransients
  519.      *            whether to include transient fields
  520.      * @param outputStatics
  521.      *            whether to include static fields
  522.      * @since 2.1
  523.      */
  524.     public <T> ReflectionToStringBuilder(
  525.             final T object, final ToStringStyle style, final StringBuffer buffer,
  526.             final Class<? super T> reflectUpToClass, final boolean outputTransients, final boolean outputStatics) {
  527.         super(object, style, buffer);
  528.         this.setUpToClass(reflectUpToClass);
  529.         this.setAppendTransients(outputTransients);
  530.         this.setAppendStatics(outputStatics);
  531.     }

  532.     /**
  533.      * Constructs a new instance.
  534.      *
  535.      * @param <T>
  536.      *            the type of the object
  537.      * @param object
  538.      *            the Object to build a {@code toString} for
  539.      * @param style
  540.      *            the style of the {@code toString} to create, may be {@code null}
  541.      * @param buffer
  542.      *            the {@link StringBuffer} to populate, may be {@code null}
  543.      * @param reflectUpToClass
  544.      *            the superclass to reflect up to (inclusive), may be {@code null}
  545.      * @param outputTransients
  546.      *            whether to include transient fields
  547.      * @param outputStatics
  548.      *            whether to include static fields
  549.      * @param excludeNullValues
  550.      *            whether to exclude fields who value is null
  551.      * @since 3.6
  552.      */
  553.     public <T> ReflectionToStringBuilder(
  554.             final T object, final ToStringStyle style, final StringBuffer buffer,
  555.             final Class<? super T> reflectUpToClass, final boolean outputTransients, final boolean outputStatics,
  556.             final boolean excludeNullValues) {
  557.         super(object, style, buffer);
  558.         this.setUpToClass(reflectUpToClass);
  559.         this.setAppendTransients(outputTransients);
  560.         this.setAppendStatics(outputStatics);
  561.         this.setExcludeNullValues(excludeNullValues);
  562.     }

  563.     /**
  564.      * Returns whether or not to append the given {@link Field}.
  565.      * <ul>
  566.      * <li>Transient fields are appended only if {@link #isAppendTransients()} returns {@code true}.
  567.      * <li>Static fields are appended only if {@link #isAppendStatics()} returns {@code true}.
  568.      * <li>Inner class fields are not appended.</li>
  569.      * </ul>
  570.      *
  571.      * @param field
  572.      *            The Field to test.
  573.      * @return Whether or not to append the given {@link Field}.
  574.      */
  575.     protected boolean accept(final Field field) {
  576.         if (field.getName().indexOf(ClassUtils.INNER_CLASS_SEPARATOR_CHAR) != -1) {
  577.             // Reject field from inner class.
  578.             return false;
  579.         }
  580.         if (Modifier.isTransient(field.getModifiers()) && !this.isAppendTransients()) {
  581.             // Reject transient fields.
  582.             return false;
  583.         }
  584.         if (Modifier.isStatic(field.getModifiers()) && !this.isAppendStatics()) {
  585.             // Reject static fields.
  586.             return false;
  587.         }

  588.         if (this.excludeFieldNames != null
  589.             && Arrays.binarySearch(this.excludeFieldNames, field.getName()) >= 0) {
  590.             // Reject fields from the getExcludeFieldNames list.
  591.             return false;
  592.         }

  593.         if (ArrayUtils.isNotEmpty(includeFieldNames)) {
  594.             // Accept fields from the getIncludeFieldNames list. {@code null} or empty means all fields are included. All fields are included by default.
  595.             return Arrays.binarySearch(this.includeFieldNames, field.getName()) >= 0;
  596.         }

  597.         return !field.isAnnotationPresent(ToStringExclude.class);
  598.     }

  599.     /**
  600.      * Appends the fields and values defined by the given object of the given Class.
  601.      *
  602.      * <p>
  603.      * If a cycle is detected as an object is &quot;toString()'ed&quot;, such an object is rendered as if
  604.      * {@code Object.toString()} had been called and not implemented by the object.
  605.      * </p>
  606.      *
  607.      * @param clazz
  608.      *            The class of object parameter
  609.      */
  610.     protected void appendFieldsIn(final Class<?> clazz) {
  611.         if (clazz.isArray()) {
  612.             this.reflectionAppendArray(this.getObject());
  613.             return;
  614.         }
  615.         // The elements in the returned array are not sorted and are not in any particular order.
  616.         final Field[] fields = ArraySorter.sort(clazz.getDeclaredFields(), Comparator.comparing(Field::getName));
  617.         AccessibleObject.setAccessible(fields, true);
  618.         for (final Field field : fields) {
  619.             final String fieldName = field.getName();
  620.             if (this.accept(field)) {
  621.                 try {
  622.                     // Warning: Field.get(Object) creates wrappers objects
  623.                     // for primitive types.
  624.                     final Object fieldValue = this.getValue(field);
  625.                     if (!excludeNullValues || fieldValue != null) {
  626.                         this.append(fieldName, fieldValue, !field.isAnnotationPresent(ToStringSummary.class));
  627.                     }
  628.                 } catch (final IllegalAccessException e) {
  629.                     // this can't happen. Would get a Security exception instead throw a runtime exception in case the
  630.                     // impossible happens.
  631.                     throw new IllegalStateException(e);
  632.                 }
  633.             }
  634.         }
  635.     }

  636.     /**
  637.      * Gets the excludeFieldNames.
  638.      *
  639.      * @return the excludeFieldNames.
  640.      */
  641.     public String[] getExcludeFieldNames() {
  642.         return this.excludeFieldNames.clone();
  643.     }

  644.     /**
  645.      * Gets the includeFieldNames
  646.      *
  647.      * @return the includeFieldNames.
  648.      * @since 3.13.0
  649.      */
  650.     public String[] getIncludeFieldNames() {
  651.         return this.includeFieldNames.clone();
  652.     }

  653.     /**
  654.      * Gets the last super class to stop appending fields for.
  655.      *
  656.      * @return The last super class to stop appending fields for.
  657.      */
  658.     public Class<?> getUpToClass() {
  659.         return this.upToClass;
  660.     }

  661.     /**
  662.      * Calls {@code java.lang.reflect.Field.get(Object)}.
  663.      *
  664.      * @param field
  665.      *            The Field to query.
  666.      * @return The Object from the given Field.
  667.      *
  668.      * @throws IllegalArgumentException
  669.      *             see {@link java.lang.reflect.Field#get(Object)}
  670.      * @throws IllegalAccessException
  671.      *             see {@link java.lang.reflect.Field#get(Object)}
  672.      *
  673.      * @see java.lang.reflect.Field#get(Object)
  674.      */
  675.     protected Object getValue(final Field field) throws IllegalAccessException {
  676.         return field.get(this.getObject());
  677.     }

  678.     /**
  679.      * Gets whether or not to append static fields.
  680.      *
  681.      * @return Whether or not to append static fields.
  682.      * @since 2.1
  683.      */
  684.     public boolean isAppendStatics() {
  685.         return this.appendStatics;
  686.     }

  687.     /**
  688.      * Gets whether or not to append transient fields.
  689.      *
  690.      * @return Whether or not to append transient fields.
  691.      */
  692.     public boolean isAppendTransients() {
  693.         return this.appendTransients;
  694.     }

  695.     /**
  696.      * Gets whether or not to append fields whose values are null.
  697.      *
  698.      * @return Whether or not to append fields whose values are null.
  699.      * @since 3.6
  700.      */
  701.     public boolean isExcludeNullValues() {
  702.         return this.excludeNullValues;
  703.     }

  704.     /**
  705.      * Appends to the {@code toString} an {@link Object} array.
  706.      *
  707.      * @param array
  708.      *            the array to add to the {@code toString}
  709.      * @return {@code this} instance.
  710.      */
  711.     public ReflectionToStringBuilder reflectionAppendArray(final Object array) {
  712.         this.getStyle().reflectionAppendArrayDetail(this.getStringBuffer(), null, array);
  713.         return this;
  714.     }

  715.     /**
  716.      * Sets whether or not to append static fields.
  717.      *
  718.      * @param appendStatics
  719.      *            Whether or not to append static fields.
  720.      * @since 2.1
  721.      */
  722.     public void setAppendStatics(final boolean appendStatics) {
  723.         this.appendStatics = appendStatics;
  724.     }

  725.     /**
  726.      * Sets whether or not to append transient fields.
  727.      *
  728.      * @param appendTransients
  729.      *            Whether or not to append transient fields.
  730.      */
  731.     public void setAppendTransients(final boolean appendTransients) {
  732.         this.appendTransients = appendTransients;
  733.     }

  734.     /**
  735.      * Sets the field names to exclude.
  736.      *
  737.      * @param excludeFieldNamesParam
  738.      *            The excludeFieldNames to excluding from toString or {@code null}.
  739.      * @return {@code this}
  740.      */
  741.     public ReflectionToStringBuilder setExcludeFieldNames(final String... excludeFieldNamesParam) {
  742.         if (excludeFieldNamesParam == null) {
  743.             this.excludeFieldNames = null;
  744.         } else {
  745.             // clone and remove nulls
  746.             this.excludeFieldNames = ArraySorter.sort(toNoNullStringArray(excludeFieldNamesParam));
  747.         }
  748.         return this;
  749.     }

  750.     /**
  751.      * Sets whether or not to append fields whose values are null.
  752.      *
  753.      * @param excludeNullValues
  754.      *            Whether or not to append fields whose values are null.
  755.      * @since 3.6
  756.      */
  757.     public void setExcludeNullValues(final boolean excludeNullValues) {
  758.         this.excludeNullValues = excludeNullValues;
  759.     }

  760.     /**
  761.      * Sets the field names to include. {@code null} or empty means all fields are included. All fields are included by default. This method will override the default behavior.
  762.      *
  763.      * @param includeFieldNamesParam
  764.      *            The includeFieldNames that must be on toString or {@code null}.
  765.      * @return {@code this}
  766.      * @since 3.13.0
  767.      */
  768.     public ReflectionToStringBuilder setIncludeFieldNames(final String... includeFieldNamesParam) {
  769.         if (includeFieldNamesParam == null) {
  770.             this.includeFieldNames = null;
  771.         } else {
  772.             // clone and remove nulls
  773.             this.includeFieldNames = ArraySorter.sort(toNoNullStringArray(includeFieldNamesParam));
  774.         }
  775.         return this;
  776.     }

  777.     /**
  778.      * Sets the last super class to stop appending fields for.
  779.      *
  780.      * @param clazz
  781.      *            The last super class to stop appending fields for.
  782.      */
  783.     public void setUpToClass(final Class<?> clazz) {
  784.         if (clazz != null) {
  785.             final Object object = getObject();
  786.             if (object != null && !clazz.isInstance(object)) {
  787.                 throw new IllegalArgumentException("Specified class is not a superclass of the object");
  788.             }
  789.         }
  790.         this.upToClass = clazz;
  791.     }

  792.     /**
  793.      * Gets the String built by this builder.
  794.      *
  795.      * @return the built string
  796.      */
  797.     @Override
  798.     public String toString() {
  799.         if (this.getObject() == null) {
  800.             return this.getStyle().getNullText();
  801.         }

  802.         validate();

  803.         Class<?> clazz = this.getObject().getClass();
  804.         this.appendFieldsIn(clazz);
  805.         while (clazz.getSuperclass() != null && clazz != this.getUpToClass()) {
  806.             clazz = clazz.getSuperclass();
  807.             this.appendFieldsIn(clazz);
  808.         }
  809.         return super.toString();
  810.     }

  811.     /**
  812.      * Validates that include and exclude names do not intersect.
  813.      */
  814.     private void validate() {
  815.         if (ArrayUtils.containsAny(this.excludeFieldNames, (Object[]) this.includeFieldNames)) {
  816.             ToStringStyle.unregister(this.getObject());
  817.             throw new IllegalStateException("includeFieldNames and excludeFieldNames must not intersect");
  818.         }
  819.     }

  820. }