All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feilong.lib.lang3.builder.ToStringBuilder Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.3.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.feilong.lib.lang3.builder;

import com.feilong.lib.lang3.Validate;

/**
 * 

* Assists in implementing {@link Object#toString()} methods. *

* *

* This class enables a good and consistent {@code toString()} to be built for any * class or object. This class aims to simplify the process by: *

*
    *
  • allowing field names
  • *
  • handling all types consistently
  • *
  • handling nulls consistently
  • *
  • outputting arrays and multi-dimensional arrays
  • *
  • enabling the detail level to be controlled for Objects and Collections
  • *
  • handling class hierarchies
  • *
* *

* To use this class write code as follows: *

* *
 * public class Person {
 *   String name;
 *   int age;
 *   boolean smoker;
 *
 *   ...
 *
 *   public String toString() {
 *     return new ToStringBuilder(this).
 *       append("name", name).
 *       append("age", age).
 *       append("smoker", smoker).
 *       toString();
 *   }
 * }
 * 
* *

* This will produce a toString of the format: * {@code Person@7f54[name=Stephen,age=29,smoker=false]} *

* *

* To add the superclass {@code toString}, use {@link #appendSuper}. * To append the {@code toString} from an object that is delegated * to (or any other object), use {@link #appendToString}. *

* *

* Alternatively, there is a method that uses reflection to determine * the fields to test. Because these fields are usually private, the method, * {@code reflectionToString}, uses {@code AccessibleObject.setAccessible} to * change the visibility of the fields. This will fail under a security manager, * unless the appropriate permissions are set up correctly. It is also * slower than testing explicitly. *

* *

* A typical invocation for this method would look like: *

* *
 * 
 * public String toString(){
 *     return ToStringBuilder.reflectionToString(this);
 * }
 * 
* *

* You can also use the builder to debug 3rd party objects: *

* *
 * System.out.println("An object: " + ToStringBuilder.reflectionToString(anObject));
 * 
* *

* The exact format of the {@code toString} is determined by * the {@link ToStringStyle} passed into the constructor. *

* * @since 1.0 */ public class ToStringBuilder implements Builder{ /** * The default style of output to use, not null. */ private static volatile ToStringStyle defaultStyle = ToStringStyle.DEFAULT_STYLE; //---------------------------------------------------------------------------- /** *

* Gets the default {@code ToStringStyle} to use. *

* *

* This method gets a singleton default value, typically for the whole JVM. * Changing this default should generally only be done during application startup. * It is recommended to pass a {@code ToStringStyle} to the constructor instead * of using this global default. *

* *

* This method can be used from multiple threads. * Internally, a {@code volatile} variable is used to provide the guarantee * that the latest value set using {@link #setDefaultStyle} is the value returned. * It is strongly recommended that the default style is only changed during application startup. *

* *

* One reason for changing the default could be to have a verbose style during * development and a compact style in production. *

* * @return the default {@code ToStringStyle}, never null */ public static ToStringStyle getDefaultStyle(){ return defaultStyle; } /** *

* Sets the default {@code ToStringStyle} to use. *

* *

* This method sets a singleton default value, typically for the whole JVM. * Changing this default should generally only be done during application startup. * It is recommended to pass a {@code ToStringStyle} to the constructor instead * of changing this global default. *

* *

* This method is not intended for use from multiple threads. * Internally, a {@code volatile} variable is used to provide the guarantee * that the latest value set is the value returned from {@link #getDefaultStyle}. *

* * @param style * the default {@code ToStringStyle} * @throws IllegalArgumentException * if the style is {@code null} */ public static void setDefaultStyle(final ToStringStyle style){ defaultStyle = Validate.notNull(style, "The style must not be null"); } //---------------------------------------------------------------------------- /** *

* Uses {@code ReflectionToStringBuilder} to generate a * {@code toString} for the specified object. *

* * @param object * the Object to be output * @return the String result * @see ReflectionToStringBuilder#toString(Object) */ public static String reflectionToString(final Object object){ return ReflectionToStringBuilder.toString(object); } /** *

* Uses {@code ReflectionToStringBuilder} to generate a * {@code toString} for the specified object. *

* * @param object * the Object to be output * @param style * the style of the {@code toString} to create, may be {@code null} * @return the String result * @see ReflectionToStringBuilder#toString(Object,ToStringStyle) */ public static String reflectionToString(final Object object,final ToStringStyle style){ return ReflectionToStringBuilder.toString(object, style); } /** *

* Uses {@code ReflectionToStringBuilder} to generate a * {@code toString} for the specified object. *

* * @param object * the Object to be output * @param style * the style of the {@code toString} to create, may be {@code null} * @param outputTransients * whether to include transient fields * @return the String result * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean) */ public static String reflectionToString(final Object object,final ToStringStyle style,final boolean outputTransients){ return ReflectionToStringBuilder.toString(object, style, outputTransients, false, null); } /** *

* Uses {@code ReflectionToStringBuilder} to generate a * {@code toString} for the specified object. *

* * @param * the type of the object * @param object * the Object to be output * @param style * the style of the {@code toString} to create, may be {@code null} * @param outputTransients * whether to include transient fields * @param reflectUpToClass * the superclass to reflect up to (inclusive), may be {@code null} * @return the String result * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean,boolean,Class) * @since 2.0 */ public static String reflectionToString( final T object, final ToStringStyle style, final boolean outputTransients, final Class reflectUpToClass){ return ReflectionToStringBuilder.toString(object, style, outputTransients, false, reflectUpToClass); } //---------------------------------------------------------------------------- /** * Current toString buffer, not null. */ private final StringBuffer buffer; /** * The object being output, may be null. */ private final Object object; /** * The style of output to use, not null. */ private final ToStringStyle style; /** *

* Constructs a builder for the specified object using the default output style. *

* *

* This default style is obtained from {@link #getDefaultStyle()}. *

* * @param object * the Object to build a {@code toString} for, not recommended to be null */ public ToStringBuilder(final Object object){ this(object, null, null); } /** *

* Constructs a builder for the specified object using the defined output style. *

* *

* If the style is {@code null}, the default style is used. *

* * @param object * the Object to build a {@code toString} for, not recommended to be null * @param style * the style of the {@code toString} to create, null uses the default style */ public ToStringBuilder(final Object object, final ToStringStyle style){ this(object, style, null); } /** *

* Constructs a builder for the specified object. *

* *

* If the style is {@code null}, the default style is used. *

* *

* If the buffer is {@code null}, a new one is created. *

* * @param object * the Object to build a {@code toString} for, not recommended to be null * @param style * the style of the {@code toString} to create, null uses the default style * @param buffer * the {@code StringBuffer} to populate, may be null */ public ToStringBuilder(final Object object, ToStringStyle style, StringBuffer buffer){ if (style == null){ style = getDefaultStyle(); } if (buffer == null){ buffer = new StringBuffer(512); } this.buffer = buffer; this.style = style; this.object = object; style.appendStart(buffer, object); } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code boolean} * value. *

* * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final boolean value){ style.append(buffer, null, value); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code boolean} * array. *

* * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final boolean[] array){ style.append(buffer, null, array, null); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code byte} * value. *

* * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final byte value){ style.append(buffer, null, value); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code byte} * array. *

* * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final byte[] array){ style.append(buffer, null, array, null); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code char} * value. *

* * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final char value){ style.append(buffer, null, value); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code char} * array. *

* * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final char[] array){ style.append(buffer, null, array, null); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code double} * value. *

* * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final double value){ style.append(buffer, null, value); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code double} * array. *

* * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final double[] array){ style.append(buffer, null, array, null); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code float} * value. *

* * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final float value){ style.append(buffer, null, value); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code float} * array. *

* * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final float[] array){ style.append(buffer, null, array, null); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} an {@code int} * value. *

* * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final int value){ style.append(buffer, null, value); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} an {@code int} * array. *

* * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final int[] array){ style.append(buffer, null, array, null); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code long} * value. *

* * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final long value){ style.append(buffer, null, value); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code long} * array. *

* * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final long[] array){ style.append(buffer, null, array, null); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} an {@code Object} * value. *

* * @param obj * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final Object obj){ style.append(buffer, null, obj, null); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} an {@code Object} * array. *

* * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final Object[] array){ style.append(buffer, null, array, null); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code short} * value. *

* * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final short value){ style.append(buffer, null, value); return this; } //---------------------------------------------------------------------------- /** *

* Append to the {@code toString} a {@code short} * array. *

* * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final short[] array){ style.append(buffer, null, array, null); return this; } /** *

* Append to the {@code toString} a {@code boolean} * value. *

* * @param fieldName * the field name * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final boolean value){ style.append(buffer, fieldName, value); return this; } /** *

* Append to the {@code toString} a {@code boolean} * array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code hashCode} * @return this */ public ToStringBuilder append(final String fieldName,final boolean[] array){ style.append(buffer, fieldName, array, null); return this; } /** *

* Append to the {@code toString} a {@code boolean} * array. *

* *

* A boolean parameter controls the level of detail to show. * Setting {@code true} will output the array in full. Setting * {@code false} will output a summary, typically the size of * the array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @param fullDetail * {@code true} for detail, {@code false} * for summary info * @return this */ public ToStringBuilder append(final String fieldName,final boolean[] array,final boolean fullDetail){ style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)); return this; } /** *

* Append to the {@code toString} an {@code byte} * value. *

* * @param fieldName * the field name * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final byte value){ style.append(buffer, fieldName, value); return this; } /** *

* Append to the {@code toString} a {@code byte} array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final byte[] array){ style.append(buffer, fieldName, array, null); return this; } /** *

* Append to the {@code toString} a {@code byte} * array. *

* *

* A boolean parameter controls the level of detail to show. * Setting {@code true} will output the array in full. Setting * {@code false} will output a summary, typically the size of * the array. * * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @param fullDetail * {@code true} for detail, {@code false} * for summary info * @return this */ public ToStringBuilder append(final String fieldName,final byte[] array,final boolean fullDetail){ style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)); return this; } /** *

* Append to the {@code toString} a {@code char} * value. *

* * @param fieldName * the field name * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final char value){ style.append(buffer, fieldName, value); return this; } /** *

* Append to the {@code toString} a {@code char} * array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final char[] array){ style.append(buffer, fieldName, array, null); return this; } /** *

* Append to the {@code toString} a {@code char} * array. *

* *

* A boolean parameter controls the level of detail to show. * Setting {@code true} will output the array in full. Setting * {@code false} will output a summary, typically the size of * the array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @param fullDetail * {@code true} for detail, {@code false} * for summary info * @return this */ public ToStringBuilder append(final String fieldName,final char[] array,final boolean fullDetail){ style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)); return this; } /** *

* Append to the {@code toString} a {@code double} * value. *

* * @param fieldName * the field name * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final double value){ style.append(buffer, fieldName, value); return this; } /** *

* Append to the {@code toString} a {@code double} * array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final double[] array){ style.append(buffer, fieldName, array, null); return this; } /** *

* Append to the {@code toString} a {@code double} * array. *

* *

* A boolean parameter controls the level of detail to show. * Setting {@code true} will output the array in full. Setting * {@code false} will output a summary, typically the size of * the array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @param fullDetail * {@code true} for detail, {@code false} * for summary info * @return this */ public ToStringBuilder append(final String fieldName,final double[] array,final boolean fullDetail){ style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)); return this; } /** *

* Append to the {@code toString} an {@code float} * value. *

* * @param fieldName * the field name * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final float value){ style.append(buffer, fieldName, value); return this; } /** *

* Append to the {@code toString} a {@code float} * array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final float[] array){ style.append(buffer, fieldName, array, null); return this; } /** *

* Append to the {@code toString} a {@code float} * array. *

* *

* A boolean parameter controls the level of detail to show. * Setting {@code true} will output the array in full. Setting * {@code false} will output a summary, typically the size of * the array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @param fullDetail * {@code true} for detail, {@code false} * for summary info * @return this */ public ToStringBuilder append(final String fieldName,final float[] array,final boolean fullDetail){ style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)); return this; } /** *

* Append to the {@code toString} an {@code int} * value. *

* * @param fieldName * the field name * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final int value){ style.append(buffer, fieldName, value); return this; } /** *

* Append to the {@code toString} an {@code int} * array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final int[] array){ style.append(buffer, fieldName, array, null); return this; } /** *

* Append to the {@code toString} an {@code int} * array. *

* *

* A boolean parameter controls the level of detail to show. * Setting {@code true} will output the array in full. Setting * {@code false} will output a summary, typically the size of * the array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @param fullDetail * {@code true} for detail, {@code false} * for summary info * @return this */ public ToStringBuilder append(final String fieldName,final int[] array,final boolean fullDetail){ style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)); return this; } /** *

* Append to the {@code toString} a {@code long} * value. *

* * @param fieldName * the field name * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final long value){ style.append(buffer, fieldName, value); return this; } /** *

* Append to the {@code toString} a {@code long} * array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final long[] array){ style.append(buffer, fieldName, array, null); return this; } /** *

* Append to the {@code toString} a {@code long} * array. *

* *

* A boolean parameter controls the level of detail to show. * Setting {@code true} will output the array in full. Setting * {@code false} will output a summary, typically the size of * the array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @param fullDetail * {@code true} for detail, {@code false} * for summary info * @return this */ public ToStringBuilder append(final String fieldName,final long[] array,final boolean fullDetail){ style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)); return this; } /** *

* Append to the {@code toString} an {@code Object} * value. *

* * @param fieldName * the field name * @param obj * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final Object obj){ style.append(buffer, fieldName, obj, null); return this; } /** *

* Append to the {@code toString} an {@code Object} * value. *

* * @param fieldName * the field name * @param obj * the value to add to the {@code toString} * @param fullDetail * {@code true} for detail, * {@code false} for summary info * @return this */ public ToStringBuilder append(final String fieldName,final Object obj,final boolean fullDetail){ style.append(buffer, fieldName, obj, Boolean.valueOf(fullDetail)); return this; } /** *

* Append to the {@code toString} an {@code Object} * array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final Object[] array){ style.append(buffer, fieldName, array, null); return this; } /** *

* Append to the {@code toString} an {@code Object} * array. *

* *

* A boolean parameter controls the level of detail to show. * Setting {@code true} will output the array in full. Setting * {@code false} will output a summary, typically the size of * the array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @param fullDetail * {@code true} for detail, {@code false} * for summary info * @return this */ public ToStringBuilder append(final String fieldName,final Object[] array,final boolean fullDetail){ style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)); return this; } /** *

* Append to the {@code toString} an {@code short} * value. *

* * @param fieldName * the field name * @param value * the value to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final short value){ style.append(buffer, fieldName, value); return this; } /** *

* Append to the {@code toString} a {@code short} * array. *

* * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @return this */ public ToStringBuilder append(final String fieldName,final short[] array){ style.append(buffer, fieldName, array, null); return this; } /** *

* Append to the {@code toString} a {@code short} * array. *

* *

* A boolean parameter controls the level of detail to show. * Setting {@code true} will output the array in full. Setting * {@code false} will output a summary, typically the size of * the array. * * @param fieldName * the field name * @param array * the array to add to the {@code toString} * @param fullDetail * {@code true} for detail, {@code false} * for summary info * @return this */ public ToStringBuilder append(final String fieldName,final short[] array,final boolean fullDetail){ style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail)); return this; } //---------------------------------------------------------------------------- /** *

* Append the {@code toString} from the superclass. *

* *

* This method assumes that the superclass uses the same {@code ToStringStyle} * as this one. *

* *

* If {@code superToString} is {@code null}, no change is made. *

* * @param superToString * the result of {@code super.toString()} * @return this * @since 2.0 */ public ToStringBuilder appendSuper(final String superToString){ if (superToString != null){ style.appendSuper(buffer, superToString); } return this; } /** *

* Append the {@code toString} from another object. *

* *

* This method is useful where a class delegates most of the implementation of * its properties to another class. You can then call {@code toString()} on * the other class and pass the result into this method. *

* *
     * 
     * private AnotherObject delegate;
     * 
     * private String fieldInThisClass;
     *
     * public String toString(){
     *     return new ToStringBuilder(this).appendToString(delegate.toString()).append(fieldInThisClass).toString();
     * }
     * 
* *

* This method assumes that the other object uses the same {@code ToStringStyle} * as this one. *

* *

* If the {@code toString} is {@code null}, no change is made. *

* * @param toString * the result of {@code toString()} on another object * @return this * @since 2.0 */ public ToStringBuilder appendToString(final String toString){ if (toString != null){ style.appendToString(buffer, toString); } return this; } /** *

* Returns the {@code Object} being output. *

* * @return The object being output. * @since 2.0 */ public Object getObject(){ return object; } /** *

* Gets the {@code StringBuffer} being populated. *

* * @return the {@code StringBuffer} being populated */ public StringBuffer getStringBuffer(){ return buffer; } //---------------------------------------------------------------------------- /** *

* Gets the {@code ToStringStyle} being used. *

* * @return the {@code ToStringStyle} being used * @since 2.0 */ public ToStringStyle getStyle(){ return style; } /** *

* Returns the built {@code toString}. *

* *

* This method appends the end of data indicator, and can only be called once. * Use {@link #getStringBuffer} to get the current string state. *

* *

* If the object is {@code null}, return the style's {@code nullText} *

* * @return the String {@code toString} */ @Override public String toString(){ if (this.getObject() == null){ this.getStringBuffer().append(this.getStyle().getNullText()); }else{ style.appendEnd(this.getStringBuffer(), this.getObject()); } return this.getStringBuffer().toString(); } /** * Returns the String that was build as an object representation. The * default implementation utilizes the {@link #toString()} implementation. * * @return the String {@code toString} * * @see #toString() * * @since 3.0 */ @Override public String build(){ return toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy