001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * https://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.lang3.builder; 018 019import java.util.Objects; 020 021import org.apache.commons.lang3.ObjectUtils; 022 023/** 024 * Assists in implementing {@link Object#toString()} methods. 025 * 026 * <p> 027 * This class enables a good and consistent {@code toString()} to be built for any 028 * class or object. This class aims to simplify the process by: 029 * </p> 030 * <ul> 031 * <li>allowing field names</li> 032 * <li>handling all types consistently</li> 033 * <li>handling nulls consistently</li> 034 * <li>outputting arrays and multi-dimensional arrays</li> 035 * <li>enabling the detail level to be controlled for Objects and Collections</li> 036 * <li>handling class hierarchies</li> 037 * </ul> 038 * 039 * <p> 040 * To use this class write code as follows: 041 * </p> 042 * 043 * <pre> 044 * public class Person { 045 * String name; 046 * int age; 047 * boolean smoker; 048 * 049 * ... 050 * 051 * public String toString() { 052 * return new ToStringBuilder(this). 053 * append("name", name). 054 * append("age", age). 055 * append("smoker", smoker). 056 * toString(); 057 * } 058 * } 059 * </pre> 060 * 061 * <p> 062 * This will produce a toString of the format: 063 * {@code Person@7f54[name=Stephen,age=29,smoker=false]} 064 * </p> 065 * 066 * <p> 067 * To add the superclass {@code toString}, use {@link #appendSuper}. 068 * To append the {@code toString} from an object that is delegated 069 * to (or any other object), use {@link #appendToString}. 070 * </p> 071 * 072 * <p> 073 * Alternatively, there is a method that uses reflection to determine 074 * the fields to test. Because these fields are usually private, the method, 075 * {@code reflectionToString}, uses {@code AccessibleObject.setAccessible} to 076 * change the visibility of the fields. This will fail under a security manager, 077 * unless the appropriate permissions are set up correctly. It is also 078 * slower than testing explicitly. 079 * </p> 080 * <p> 081 * See also {@link AbstractBuilder#setForceAccessible(boolean)} 082 * </p> 083 * 084 * <p> 085 * A typical invocation for this method would look like: 086 * </p> 087 * 088 * <pre> 089 * public String toString() { 090 * return ToStringBuilder.reflectionToString(this); 091 * } 092 * </pre> 093 * 094 * <p> 095 * You can also use the builder to debug 3rd party objects: 096 * </p> 097 * 098 * <pre> 099 * System.out.println("An object: " + ToStringBuilder.reflectionToString(anObject)); 100 * </pre> 101 * 102 * <p> 103 * The exact format of the {@code toString} is determined by 104 * the {@link ToStringStyle} passed into the constructor. 105 * </p> 106 * 107 * @see AbstractBuilder#setForceAccessible(boolean) 108 * @since 1.0 109 */ 110public class ToStringBuilder extends AbstractReflection implements Builder<String> { 111 112 /** 113 * Builds instances of CompareToBuilder. 114 * 115 * @since 3.21.0 116 */ 117 public static class Builder extends AbstractBuilder<Builder> { 118 119 private Object object; 120 private ToStringStyle style; 121 private StringBuffer buffer; 122 123 /** 124 * Constructs a new Builder instance. 125 */ 126 private Builder() { 127 // empty 128 } 129 130 @Override 131 public ToStringBuilder get() { 132 return new ToStringBuilder(this); 133 } 134 135 /** 136 * Sets the {@link StringBuffer} to populate, may be null. 137 * 138 * @param buffer The {@link StringBuffer} to populate, may be null 139 * @return {@code this} builder instance. 140 */ 141 public Builder setBuffer(final StringBuffer buffer) { 142 this.buffer = buffer; 143 return asThis(); 144 } 145 146 /** 147 * Sets the Object to build a {@code toString} for, not recommended to be null. 148 * 149 * @param object The Object to build a {@code toString} for, not recommended to be null. 150 * @return {@code this} builder instance. 151 */ 152 public Builder setObject(final Object object) { 153 this.object = object; 154 return asThis(); 155 } 156 157 /** 158 * Sets the style of the {@code toString} to create, null uses the default style. 159 * 160 * @param style The style of the {@code toString} to create, null uses the default style 161 * @return {@code this} builder instance. 162 */ 163 public Builder setStyle(final ToStringStyle style) { 164 this.style = style; 165 return asThis(); 166 } 167 } 168 169 /** 170 * The default style of output to use, not null. 171 */ 172 private static volatile ToStringStyle defaultStyle = ToStringStyle.DEFAULT_STYLE; 173 174 /** 175 * Constructs a new Builder. 176 * 177 * @return A new Builder. 178 * @since 3.21.0 179 */ 180 public static Builder builder() { 181 return new Builder(); 182 } 183 184 /** 185 * Gets the default {@link ToStringStyle} to use. 186 * 187 * <p> 188 * This method gets a singleton default value, typically for the whole JVM. 189 * Changing this default should generally only be done during application startup. 190 * It is recommended to pass a {@link ToStringStyle} to the constructor instead 191 * of using this global default. 192 * </p> 193 * 194 * <p> 195 * This method can be used from multiple threads. 196 * Internally, a {@code volatile} variable is used to provide the guarantee 197 * that the latest value set using {@link #setDefaultStyle} is the value returned. 198 * It is strongly recommended that the default style is only changed during application startup. 199 * </p> 200 * 201 * <p> 202 * One reason for changing the default could be to have a verbose style during 203 * development and a compact style in production. 204 * </p> 205 * 206 * @return The default {@link ToStringStyle}, never null 207 */ 208 public static ToStringStyle getDefaultStyle() { 209 return defaultStyle; 210 } 211 212 /** 213 * Uses {@link ReflectionToStringBuilder} to generate a 214 * {@code toString} for the specified object. 215 * 216 * @param object The Object to be output 217 * @return The String result 218 * @see ReflectionToStringBuilder#toString(Object) 219 */ 220 public static String reflectionToString(final Object object) { 221 return ReflectionToStringBuilder.toString(object); 222 } 223 224 /** 225 * Uses {@link ReflectionToStringBuilder} to generate a 226 * {@code toString} for the specified object. 227 * 228 * @param object The Object to be output 229 * @param style The style of the {@code toString} to create, may be {@code null} 230 * @return The String result 231 * @see ReflectionToStringBuilder#toString(Object,ToStringStyle) 232 */ 233 public static String reflectionToString(final Object object, final ToStringStyle style) { 234 return ReflectionToStringBuilder.toString(object, style); 235 } 236 237 /** 238 * Uses {@link ReflectionToStringBuilder} to generate a 239 * {@code toString} for the specified object. 240 * 241 * @param object The Object to be output 242 * @param style The style of the {@code toString} to create, may be {@code null} 243 * @param outputTransients whether to include transient fields 244 * @return The String result 245 * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean) 246 */ 247 public static String reflectionToString(final Object object, final ToStringStyle style, final boolean outputTransients) { 248 return ReflectionToStringBuilder.toString(object, style, outputTransients, false, null); 249 } 250 251 /** 252 * Uses {@link ReflectionToStringBuilder} to generate a 253 * {@code toString} for the specified object. 254 * 255 * @param <T> The type of the object 256 * @param object The Object to be output 257 * @param style The style of the {@code toString} to create, may be {@code null} 258 * @param outputTransients whether to include transient fields 259 * @param reflectUpToClass The superclass to reflect up to (inclusive), may be {@code null} 260 * @return The String result 261 * @see ReflectionToStringBuilder#toString(Object,ToStringStyle,boolean,boolean,Class) 262 * @since 2.0 263 */ 264 public static <T> String reflectionToString( 265 final T object, 266 final ToStringStyle style, 267 final boolean outputTransients, 268 final Class<? super T> reflectUpToClass) { 269 return ReflectionToStringBuilder.toString(object, style, outputTransients, false, reflectUpToClass); 270 } 271 272 /** 273 * Sets the default {@link ToStringStyle} to use. 274 * 275 * <p> 276 * This method sets a singleton default value, typically for the whole JVM. 277 * Changing this default should generally only be done during application startup. 278 * It is recommended to pass a {@link ToStringStyle} to the constructor instead 279 * of changing this global default. 280 * </p> 281 * 282 * <p> 283 * This method is not intended for use from multiple threads. 284 * Internally, a {@code volatile} variable is used to provide the guarantee 285 * that the latest value set is the value returned from {@link #getDefaultStyle}. 286 * </p> 287 * 288 * @param style The default {@link ToStringStyle} 289 * @throws NullPointerException Thrown if the style is {@code null}. 290 */ 291 public static void setDefaultStyle(final ToStringStyle style) { 292 defaultStyle = Objects.requireNonNull(style, "style"); 293 } 294 295 /** 296 * Current toString buffer, not null. 297 */ 298 private final StringBuffer buffer; 299 300 /** 301 * The object being output, may be null. 302 */ 303 private final Object object; 304 305 /** 306 * The style of output to use, not null. 307 */ 308 private final ToStringStyle style; 309 310 /** 311 * Visited-object tracking for this builder's output buffer. 312 */ 313 private final ToStringStyle.Traversal traversal; 314 315 private ToStringBuilder(final Builder builder) { 316 super(builder); 317 this.style = builder.style != null ? builder.style : getDefaultStyle(); 318 this.buffer = builder.buffer != null ? builder.buffer : new StringBuffer(512); 319 this.object = builder.object; 320 this.traversal = ToStringStyle.getTraversal(buffer); 321 appenTraversal(() -> style.appendStart(buffer, object)); 322 } 323 324 /** 325 * Constructs a builder for the specified object using the default output style. 326 * 327 * <p> 328 * This default style is obtained from {@link #getDefaultStyle()}. 329 * </p> 330 * 331 * @param object The Object to build a {@code toString} for, not recommended to be null 332 */ 333 public ToStringBuilder(final Object object) { 334 this(object, null, null); 335 } 336 337 /** 338 * Constructs a builder for the specified object using the defined output style. 339 * 340 * <p> 341 * If the style is {@code null}, the default style is used. 342 * </p> 343 * 344 * @param object The Object to build a {@code toString} for, not recommended to be null 345 * @param style The style of the {@code toString} to create, null uses the default style 346 */ 347 public ToStringBuilder(final Object object, final ToStringStyle style) { 348 this(object, style, null); 349 } 350 351 /** 352 * Constructs a builder for the specified object. 353 * 354 * <p> 355 * If the style is {@code null}, the default style is used. 356 * </p> 357 * 358 * <p> 359 * If the buffer is {@code null}, a new one is created. 360 * </p> 361 * 362 * @param object The Object to build a {@code toString} for, not recommended to be null 363 * @param style The style of the {@code toString} to create, null uses the default style 364 * @param buffer The {@link StringBuffer} to populate, may be null 365 */ 366 public ToStringBuilder(final Object object, final ToStringStyle style, final StringBuffer buffer) { 367 this(builder().setObject(object).setStyle(style).setBuffer(buffer)); 368 } 369 370 /** 371 * Appends to the {@code toString} a {@code boolean} 372 * value. 373 * 374 * @param value The value to add to the {@code toString} 375 * @return {@code this} instance. 376 */ 377 public ToStringBuilder append(final boolean value) { 378 return appenTraversal(() -> style.append(buffer, null, value)); 379 } 380 381 /** 382 * Appends to the {@code toString} a {@code boolean} 383 * array. 384 * 385 * @param array The array to add to the {@code toString} 386 * @return {@code this} instance. 387 */ 388 public ToStringBuilder append(final boolean[] array) { 389 return appenTraversal(() -> style.append(buffer, null, array, null)); 390 } 391 392 /** 393 * Appends to the {@code toString} a {@code byte} 394 * value. 395 * 396 * @param value The value to add to the {@code toString} 397 * @return {@code this} instance. 398 */ 399 public ToStringBuilder append(final byte value) { 400 return appenTraversal(() -> style.append(buffer, null, value)); 401 } 402 403 /** 404 * Appends to the {@code toString} a {@code byte} 405 * array. 406 * 407 * @param array The array to add to the {@code toString} 408 * @return {@code this} instance. 409 */ 410 public ToStringBuilder append(final byte[] array) { 411 return appenTraversal(() -> style.append(buffer, null, array, null)); 412 } 413 414 /** 415 * Appends to the {@code toString} a {@code char} 416 * value. 417 * 418 * @param value The value to add to the {@code toString} 419 * @return {@code this} instance. 420 */ 421 public ToStringBuilder append(final char value) { 422 return appenTraversal(() -> style.append(buffer, null, value)); 423 } 424 425 /** 426 * Appends to the {@code toString} a {@code char} 427 * array. 428 * 429 * @param array The array to add to the {@code toString} 430 * @return {@code this} instance. 431 */ 432 public ToStringBuilder append(final char[] array) { 433 return appenTraversal(() -> style.append(buffer, null, array, null)); 434 } 435 436 /** 437 * Appends to the {@code toString} a {@code double} 438 * value. 439 * 440 * @param value The value to add to the {@code toString} 441 * @return {@code this} instance. 442 */ 443 public ToStringBuilder append(final double value) { 444 return appenTraversal(() -> style.append(buffer, null, value)); 445 } 446 447 /** 448 * Appends to the {@code toString} a {@code double} 449 * array. 450 * 451 * @param array The array to add to the {@code toString} 452 * @return {@code this} instance. 453 */ 454 public ToStringBuilder append(final double[] array) { 455 return appenTraversal(() -> style.append(buffer, null, array, null)); 456 } 457 458 /** 459 * Appends to the {@code toString} a {@code float} 460 * value. 461 * 462 * @param value The value to add to the {@code toString} 463 * @return {@code this} instance. 464 */ 465 public ToStringBuilder append(final float value) { 466 return appenTraversal(() -> style.append(buffer, null, value)); 467 } 468 469 /** 470 * Appends to the {@code toString} a {@code float} 471 * array. 472 * 473 * @param array The array to add to the {@code toString} 474 * @return {@code this} instance. 475 */ 476 public ToStringBuilder append(final float[] array) { 477 return appenTraversal(() -> style.append(buffer, null, array, null)); 478 } 479 480 /** 481 * Appends to the {@code toString} an {@code int} 482 * value. 483 * 484 * @param value The value to add to the {@code toString} 485 * @return {@code this} instance. 486 */ 487 public ToStringBuilder append(final int value) { 488 return appenTraversal(() -> style.append(buffer, null, value)); 489 } 490 491 /** 492 * Appends to the {@code toString} an {@code int} 493 * array. 494 * 495 * @param array The array to add to the {@code toString} 496 * @return {@code this} instance. 497 */ 498 public ToStringBuilder append(final int[] array) { 499 return appenTraversal(() -> style.append(buffer, null, array, null)); 500 } 501 502 /** 503 * Appends to the {@code toString} a {@code long} 504 * value. 505 * 506 * @param value The value to add to the {@code toString} 507 * @return {@code this} instance. 508 */ 509 public ToStringBuilder append(final long value) { 510 return appenTraversal(() -> style.append(buffer, null, value)); 511 } 512 513 /** 514 * Appends to the {@code toString} a {@code long} 515 * array. 516 * 517 * @param array The array to add to the {@code toString} 518 * @return {@code this} instance. 519 */ 520 public ToStringBuilder append(final long[] array) { 521 return appenTraversal(() -> style.append(buffer, null, array, null)); 522 } 523 524 /** 525 * Appends to the {@code toString} an {@link Object} 526 * value. 527 * 528 * @param obj The value to add to the {@code toString} 529 * @return {@code this} instance. 530 */ 531 public ToStringBuilder append(final Object obj) { 532 return appenTraversal(() -> style.append(buffer, null, obj, null)); 533 } 534 535 /** 536 * Appends to the {@code toString} an {@link Object} 537 * array. 538 * 539 * @param array The array to add to the {@code toString} 540 * @return {@code this} instance. 541 */ 542 public ToStringBuilder append(final Object[] array) { 543 return appenTraversal(() -> style.append(buffer, null, array, null)); 544 } 545 546 /** 547 * Appends to the {@code toString} a {@code short} 548 * value. 549 * 550 * @param value The value to add to the {@code toString} 551 * @return {@code this} instance. 552 */ 553 public ToStringBuilder append(final short value) { 554 return appenTraversal(() -> style.append(buffer, null, value)); 555 } 556 557 /** 558 * Appends to the {@code toString} a {@code short} 559 * array. 560 * 561 * @param array The array to add to the {@code toString} 562 * @return {@code this} instance. 563 */ 564 public ToStringBuilder append(final short[] array) { 565 return appenTraversal(() -> style.append(buffer, null, array, null)); 566 } 567 568 /** 569 * Appends to the {@code toString} a {@code boolean} 570 * value. 571 * 572 * @param fieldName The field name 573 * @param value The value to add to the {@code toString} 574 * @return {@code this} instance. 575 */ 576 public ToStringBuilder append(final String fieldName, final boolean value) { 577 return appenTraversal(() -> style.append(buffer, fieldName, value)); 578 } 579 580 /** 581 * Appends to the {@code toString} a {@code boolean} 582 * array. 583 * 584 * @param fieldName The field name 585 * @param array The array to add to the {@code hashCode} 586 * @return {@code this} instance. 587 */ 588 public ToStringBuilder append(final String fieldName, final boolean[] array) { 589 return appenTraversal(() -> style.append(buffer, fieldName, array, null)); 590 } 591 592 /** 593 * Appends to the {@code toString} a {@code boolean} 594 * array. 595 * 596 * <p> 597 * A boolean parameter controls the level of detail to show. 598 * Setting {@code true} will output the array in full. Setting 599 * {@code false} will output a summary, typically the size of 600 * the array. 601 * </p> 602 * 603 * @param fieldName The field name 604 * @param array The array to add to the {@code toString} 605 * @param fullDetail {@code true} for detail, {@code false} 606 * for summary info 607 * @return {@code this} instance. 608 */ 609 public ToStringBuilder append(final String fieldName, final boolean[] array, final boolean fullDetail) { 610 return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail))); 611 } 612 613 /** 614 * Appends to the {@code toString} an {@code byte} 615 * value. 616 * 617 * @param fieldName The field name 618 * @param value The value to add to the {@code toString} 619 * @return {@code this} instance. 620 */ 621 public ToStringBuilder append(final String fieldName, final byte value) { 622 return appenTraversal(() -> style.append(buffer, fieldName, value)); 623 } 624 625 /** 626 * Appends to the {@code toString} a {@code byte} array. 627 * 628 * @param fieldName The field name 629 * @param array The array to add to the {@code toString} 630 * @return {@code this} instance. 631 */ 632 public ToStringBuilder append(final String fieldName, final byte[] array) { 633 return appenTraversal(() -> style.append(buffer, fieldName, array, null)); 634 } 635 636 /** 637 * Appends to the {@code toString} a {@code byte} 638 * array. 639 * 640 * <p> 641 * A boolean parameter controls the level of detail to show. 642 * Setting {@code true} will output the array in full. Setting 643 * {@code false} will output a summary, typically the size of 644 * the array. 645 * </p> 646 * 647 * @param fieldName The field name 648 * @param array The array to add to the {@code toString} 649 * @param fullDetail {@code true} for detail, {@code false} 650 * for summary info 651 * @return {@code this} instance. 652 */ 653 public ToStringBuilder append(final String fieldName, final byte[] array, final boolean fullDetail) { 654 return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail))); 655 } 656 657 /** 658 * Appends to the {@code toString} a {@code char} 659 * value. 660 * 661 * @param fieldName The field name 662 * @param value The value to add to the {@code toString} 663 * @return {@code this} instance. 664 */ 665 public ToStringBuilder append(final String fieldName, final char value) { 666 return appenTraversal(() -> style.append(buffer, fieldName, value)); 667 } 668 669 /** 670 * Appends to the {@code toString} a {@code char} 671 * array. 672 * 673 * @param fieldName The field name 674 * @param array The array to add to the {@code toString} 675 * @return {@code this} instance. 676 */ 677 public ToStringBuilder append(final String fieldName, final char[] array) { 678 return appenTraversal(() -> style.append(buffer, fieldName, array, null)); 679 } 680 681 /** 682 * Appends to the {@code toString} a {@code char} 683 * array. 684 * 685 * <p> 686 * A boolean parameter controls the level of detail to show. 687 * Setting {@code true} will output the array in full. Setting 688 * {@code false} will output a summary, typically the size of 689 * the array. 690 * </p> 691 * 692 * @param fieldName The field name 693 * @param array The array to add to the {@code toString} 694 * @param fullDetail {@code true} for detail, {@code false} 695 * for summary info 696 * @return {@code this} instance. 697 */ 698 public ToStringBuilder append(final String fieldName, final char[] array, final boolean fullDetail) { 699 return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail))); 700 } 701 702 /** 703 * Appends to the {@code toString} a {@code double} 704 * value. 705 * 706 * @param fieldName The field name 707 * @param value The value to add to the {@code toString} 708 * @return {@code this} instance. 709 */ 710 public ToStringBuilder append(final String fieldName, final double value) { 711 return appenTraversal(() -> style.append(buffer, fieldName, value)); 712 } 713 714 /** 715 * Appends to the {@code toString} a {@code double} 716 * array. 717 * 718 * @param fieldName The field name 719 * @param array The array to add to the {@code toString} 720 * @return {@code this} instance. 721 */ 722 public ToStringBuilder append(final String fieldName, final double[] array) { 723 return appenTraversal(() -> style.append(buffer, fieldName, array, null)); 724 } 725 726 /** 727 * Appends to the {@code toString} a {@code double} 728 * array. 729 * 730 * <p> 731 * A boolean parameter controls the level of detail to show. 732 * Setting {@code true} will output the array in full. Setting 733 * {@code false} will output a summary, typically the size of 734 * the array. 735 * </p> 736 * 737 * @param fieldName The field name 738 * @param array The array to add to the {@code toString} 739 * @param fullDetail {@code true} for detail, {@code false} 740 * for summary info 741 * @return {@code this} instance. 742 */ 743 public ToStringBuilder append(final String fieldName, final double[] array, final boolean fullDetail) { 744 return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail))); 745 } 746 747 /** 748 * Appends to the {@code toString} an {@code float} 749 * value. 750 * 751 * @param fieldName The field name 752 * @param value The value to add to the {@code toString} 753 * @return {@code this} instance. 754 */ 755 public ToStringBuilder append(final String fieldName, final float value) { 756 return appenTraversal(() -> style.append(buffer, fieldName, value)); 757 } 758 759 /** 760 * Appends to the {@code toString} a {@code float} 761 * array. 762 * 763 * @param fieldName The field name 764 * @param array The array to add to the {@code toString} 765 * @return {@code this} instance. 766 */ 767 public ToStringBuilder append(final String fieldName, final float[] array) { 768 return appenTraversal(() -> style.append(buffer, fieldName, array, null)); 769 } 770 771 /** 772 * Appends to the {@code toString} a {@code float} 773 * array. 774 * 775 * <p> 776 * A boolean parameter controls the level of detail to show. 777 * Setting {@code true} will output the array in full. Setting 778 * {@code false} will output a summary, typically the size of 779 * the array. 780 * </p> 781 * 782 * @param fieldName The field name 783 * @param array The array to add to the {@code toString} 784 * @param fullDetail {@code true} for detail, {@code false} 785 * for summary info 786 * @return {@code this} instance. 787 */ 788 public ToStringBuilder append(final String fieldName, final float[] array, final boolean fullDetail) { 789 return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail))); 790 } 791 792 /** 793 * Appends to the {@code toString} an {@code int} 794 * value. 795 * 796 * @param fieldName The field name 797 * @param value The value to add to the {@code toString} 798 * @return {@code this} instance. 799 */ 800 public ToStringBuilder append(final String fieldName, final int value) { 801 return appenTraversal(() -> style.append(buffer, fieldName, value)); 802 } 803 804 /** 805 * Appends to the {@code toString} an {@code int} 806 * array. 807 * 808 * @param fieldName The field name 809 * @param array The array to add to the {@code toString} 810 * @return {@code this} instance. 811 */ 812 public ToStringBuilder append(final String fieldName, final int[] array) { 813 return appenTraversal(() -> style.append(buffer, fieldName, array, null)); 814 } 815 816 /** 817 * Appends to the {@code toString} an {@code int} 818 * array. 819 * 820 * <p> 821 * A boolean parameter controls the level of detail to show. 822 * Setting {@code true} will output the array in full. Setting 823 * {@code false} will output a summary, typically the size of 824 * the array. 825 * </p> 826 * 827 * @param fieldName The field name 828 * @param array The array to add to the {@code toString} 829 * @param fullDetail {@code true} for detail, {@code false} 830 * for summary info 831 * @return {@code this} instance. 832 */ 833 public ToStringBuilder append(final String fieldName, final int[] array, final boolean fullDetail) { 834 return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail))); 835 } 836 837 /** 838 * Appends to the {@code toString} a {@code long} 839 * value. 840 * 841 * @param fieldName The field name 842 * @param value The value to add to the {@code toString} 843 * @return {@code this} instance. 844 */ 845 public ToStringBuilder append(final String fieldName, final long value) { 846 return appenTraversal(() -> style.append(buffer, fieldName, value)); 847 } 848 849 /** 850 * Appends to the {@code toString} a {@code long} 851 * array. 852 * 853 * @param fieldName The field name 854 * @param array The array to add to the {@code toString} 855 * @return {@code this} instance. 856 */ 857 public ToStringBuilder append(final String fieldName, final long[] array) { 858 return appenTraversal(() -> style.append(buffer, fieldName, array, null)); 859 } 860 861 /** 862 * Appends to the {@code toString} a {@code long} 863 * array. 864 * 865 * <p> 866 * A boolean parameter controls the level of detail to show. 867 * Setting {@code true} will output the array in full. Setting 868 * {@code false} will output a summary, typically the size of 869 * the array. 870 * </p> 871 * 872 * @param fieldName The field name 873 * @param array The array to add to the {@code toString} 874 * @param fullDetail {@code true} for detail, {@code false} 875 * for summary info 876 * @return {@code this} instance. 877 */ 878 public ToStringBuilder append(final String fieldName, final long[] array, final boolean fullDetail) { 879 return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail))); 880 } 881 882 /** 883 * Appends to the {@code toString} an {@link Object} 884 * value. 885 * 886 * @param fieldName The field name 887 * @param obj The value to add to the {@code toString} 888 * @return {@code this} instance. 889 */ 890 public ToStringBuilder append(final String fieldName, final Object obj) { 891 return appenTraversal(() -> style.append(buffer, fieldName, obj, null)); 892 } 893 894 /** 895 * Appends to the {@code toString} an {@link Object} 896 * value. 897 * 898 * @param fieldName The field name 899 * @param obj The value to add to the {@code toString} 900 * @param fullDetail {@code true} for detail, 901 * {@code false} for summary info 902 * @return {@code this} instance. 903 */ 904 public ToStringBuilder append(final String fieldName, final Object obj, final boolean fullDetail) { 905 return appenTraversal(() -> style.append(buffer, fieldName, obj, Boolean.valueOf(fullDetail))); 906 } 907 908 /** 909 * Appends to the {@code toString} an {@link Object} 910 * array. 911 * 912 * @param fieldName The field name 913 * @param array The array to add to the {@code toString} 914 * @return {@code this} instance. 915 */ 916 public ToStringBuilder append(final String fieldName, final Object[] array) { 917 return appenTraversal(() -> style.append(buffer, fieldName, array, null)); 918 } 919 920 /** 921 * Appends to the {@code toString} an {@link Object} 922 * array. 923 * 924 * <p> 925 * A boolean parameter controls the level of detail to show. 926 * Setting {@code true} will output the array in full. Setting 927 * {@code false} will output a summary, typically the size of 928 * the array. 929 * </p> 930 * 931 * @param fieldName The field name 932 * @param array The array to add to the {@code toString} 933 * @param fullDetail {@code true} for detail, {@code false} 934 * for summary info 935 * @return {@code this} instance. 936 */ 937 public ToStringBuilder append(final String fieldName, final Object[] array, final boolean fullDetail) { 938 return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail))); 939 } 940 941 /** 942 * Appends to the {@code toString} an {@code short} 943 * value. 944 * 945 * @param fieldName The field name 946 * @param value The value to add to the {@code toString} 947 * @return {@code this} instance. 948 */ 949 public ToStringBuilder append(final String fieldName, final short value) { 950 return appenTraversal(() -> style.append(buffer, fieldName, value)); 951 } 952 953 /** 954 * Appends to the {@code toString} a {@code short} 955 * array. 956 * 957 * @param fieldName The field name 958 * @param array The array to add to the {@code toString} 959 * @return {@code this} instance. 960 */ 961 public ToStringBuilder append(final String fieldName, final short[] array) { 962 return appenTraversal(() -> style.append(buffer, fieldName, array, null)); 963 } 964 965 /** 966 * Appends to the {@code toString} a {@code short} 967 * array. 968 * 969 * <p> 970 * A boolean parameter controls the level of detail to show. 971 * Setting {@code true} will output the array in full. Setting 972 * {@code false} will output a summary, typically the size of 973 * the array. 974 * </p> 975 * 976 * @param fieldName The field name 977 * @param array The array to add to the {@code toString} 978 * @param fullDetail {@code true} for detail, {@code false} 979 * for summary info 980 * @return {@code this} instance. 981 */ 982 public ToStringBuilder append(final String fieldName, final short[] array, final boolean fullDetail) { 983 return appenTraversal(() -> style.append(buffer, fieldName, array, Boolean.valueOf(fullDetail))); 984 } 985 986 /** 987 * Appends with the same format as the default {@code Object toString() 988 * } method. Appends the class name followed by 989 * {@link System#identityHashCode(Object)}. 990 * 991 * @param srcObject The {@link Object} whose class name and id to output 992 * @return {@code this} instance. 993 * @throws NullPointerException Thrown if {@code srcObject} is {@code null}. 994 * @since 2.0 995 */ 996 public ToStringBuilder appendAsObjectToString(final Object srcObject) { 997 ObjectUtils.identityToString(getStringBuffer(), srcObject); 998 return this; 999 } 1000 1001 /** 1002 * Append the {@code toString} from the superclass. 1003 * 1004 * <p> 1005 * This method assumes that the superclass uses the same {@link ToStringStyle} 1006 * as this one. 1007 * </p> 1008 * 1009 * <p> 1010 * If {@code superToString} is {@code null}, no change is made. 1011 * </p> 1012 * 1013 * @param superToString The result of {@code super.toString()} 1014 * @return {@code this} instance. 1015 * @since 2.0 1016 */ 1017 public ToStringBuilder appendSuper(final String superToString) { 1018 if (superToString != null) { 1019 appenTraversal(() -> style.appendSuper(buffer, superToString)); 1020 } 1021 return this; 1022 } 1023 1024 /** 1025 * Append the {@code toString} from another object. 1026 * 1027 * <p> 1028 * This method is useful where a class delegates most of the implementation of 1029 * its properties to another class. You can then call {@code toString()} on 1030 * the other class and pass the result into this method. 1031 * </p> 1032 * 1033 * <pre> 1034 * private AnotherObject delegate; 1035 * private String fieldInThisClass; 1036 * 1037 * public String toString() { 1038 * return new ToStringBuilder(this). 1039 * appendToString(delegate.toString()). 1040 * append(fieldInThisClass). 1041 * toString(); 1042 * }</pre> 1043 * 1044 * <p> 1045 * This method assumes that the other object uses the same {@link ToStringStyle} 1046 * as this one. 1047 * </p> 1048 * 1049 * <p> 1050 * If the {@code toString} is {@code null}, no change is made. 1051 * </p> 1052 * 1053 * @param toString The result of {@code toString()} on another object 1054 * @return {@code this} instance. 1055 * @since 2.0 1056 */ 1057 public ToStringBuilder appendToString(final String toString) { 1058 if (toString != null) { 1059 appenTraversal(() -> style.appendToString(buffer, toString)); 1060 } 1061 return this; 1062 } 1063 1064 /** 1065 * Appends content while sharing visited objects with nested builders. 1066 * 1067 * @param appender the action that appends content. 1068 * @return {@code this} builder. 1069 */ 1070 ToStringBuilder appenTraversal(final Runnable appender) { 1071 final boolean owner = startTraversal(); 1072 boolean completed = false; 1073 try { 1074 appender.run(); 1075 completed = true; 1076 return this; 1077 } finally { 1078 ToStringStyle.endTraversal(buffer, traversal, owner, !completed); 1079 } 1080 } 1081 1082 /** 1083 * Returns the String that was build as an object representation. The 1084 * default implementation utilizes the {@link #toString()} implementation. 1085 * 1086 * @return The String {@code toString} 1087 * @see #toString() 1088 * @since 3.0 1089 */ 1090 @Override 1091 public String build() { 1092 return toString(); 1093 } 1094 1095 /** 1096 * Completes this builder's traversal and releases its visited objects. 1097 * 1098 * @param owner whether this builder started the active traversal. 1099 */ 1100 void endTraversal(final boolean owner) { 1101 ToStringStyle.endTraversal(buffer, traversal, owner, true); 1102 } 1103 1104 /** 1105 * Gets the {@link Object} being output. 1106 * 1107 * @return The object being output. 1108 * @since 2.0 1109 */ 1110 public Object getObject() { 1111 return object; 1112 } 1113 1114 /** 1115 * Gets the {@link StringBuffer} being populated. 1116 * 1117 * @return The {@link StringBuffer} being populated 1118 */ 1119 public StringBuffer getStringBuffer() { 1120 return buffer; 1121 } 1122 1123 /** 1124 * Gets the {@link ToStringStyle} being used. 1125 * 1126 * @return The {@link ToStringStyle} being used 1127 * @since 2.0 1128 */ 1129 public ToStringStyle getStyle() { 1130 return style; 1131 } 1132 1133 /** 1134 * Gets the traversal state associated with this builder's output buffer. 1135 * 1136 * @return the traversal state, never {@code null}. 1137 */ 1138 ToStringStyle.Traversal getTraversal() { 1139 return traversal; 1140 } 1141 1142 /** 1143 * Starts or joins the active traversal using this builder's earlier appends. 1144 * 1145 * @return whether this builder owns the active traversal. 1146 */ 1147 boolean startTraversal() { 1148 return ToStringStyle.startTraversal(traversal); 1149 } 1150 1151 1152 /** 1153 * Returns the built {@code toString}. 1154 * 1155 * <p> 1156 * This method appends the end of data indicator, and can only be called once. 1157 * Use {@link #getStringBuffer} to get the current string state. 1158 * </p> 1159 * 1160 * <p> 1161 * If the object is {@code null}, return the style's {@code nullText} 1162 * </p> 1163 * 1164 * @return The String {@code toString} 1165 */ 1166 @Override 1167 public String toString() { 1168 final boolean owner = startTraversal(); 1169 try { 1170 if (getObject() == null) { 1171 getStringBuffer().append(getStyle().getNullText()); 1172 } else { 1173 style.appendEnd(getStringBuffer(), getObject()); 1174 } 1175 return getStringBuffer().toString(); 1176 } finally { 1177 endTraversal(owner); 1178 } 1179 } 1180}