001/* 002 * Copyright 2002-2019 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.util; 018 019import java.lang.reflect.Array; 020import java.util.Arrays; 021import java.util.Collection; 022import java.util.Map; 023 024/** 025 * Miscellaneous object utility methods. 026 * 027 * <p>Mainly for internal use within the framework. 028 * 029 * <p>Thanks to Alex Ruiz for contributing several enhancements to this class! 030 * 031 * @author Juergen Hoeller 032 * @author Keith Donald 033 * @author Rod Johnson 034 * @author Rob Harrop 035 * @author Chris Beams 036 * @author Sam Brannen 037 * @since 19.03.2004 038 * @see ClassUtils 039 * @see CollectionUtils 040 * @see StringUtils 041 */ 042public abstract class ObjectUtils { 043 044 private static final int INITIAL_HASH = 7; 045 private static final int MULTIPLIER = 31; 046 047 private static final String EMPTY_STRING = ""; 048 private static final String NULL_STRING = "null"; 049 private static final String ARRAY_START = "{"; 050 private static final String ARRAY_END = "}"; 051 private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END; 052 private static final String ARRAY_ELEMENT_SEPARATOR = ", "; 053 054 055 /** 056 * Return whether the given throwable is a checked exception: 057 * that is, neither a RuntimeException nor an Error. 058 * @param ex the throwable to check 059 * @return whether the throwable is a checked exception 060 * @see java.lang.Exception 061 * @see java.lang.RuntimeException 062 * @see java.lang.Error 063 */ 064 public static boolean isCheckedException(Throwable ex) { 065 return !(ex instanceof RuntimeException || ex instanceof Error); 066 } 067 068 /** 069 * Check whether the given exception is compatible with the specified 070 * exception types, as declared in a throws clause. 071 * @param ex the exception to check 072 * @param declaredExceptions the exception types declared in the throws clause 073 * @return whether the given exception is compatible 074 */ 075 public static boolean isCompatibleWithThrowsClause(Throwable ex, Class<?>... declaredExceptions) { 076 if (!isCheckedException(ex)) { 077 return true; 078 } 079 if (declaredExceptions != null) { 080 for (Class<?> declaredException : declaredExceptions) { 081 if (declaredException.isInstance(ex)) { 082 return true; 083 } 084 } 085 } 086 return false; 087 } 088 089 /** 090 * Determine whether the given object is an array: 091 * either an Object array or a primitive array. 092 * @param obj the object to check 093 */ 094 public static boolean isArray(Object obj) { 095 return (obj != null && obj.getClass().isArray()); 096 } 097 098 /** 099 * Determine whether the given array is empty: 100 * i.e. {@code null} or of zero length. 101 * @param array the array to check 102 * @see #isEmpty(Object) 103 */ 104 public static boolean isEmpty(Object[] array) { 105 return (array == null || array.length == 0); 106 } 107 108 /** 109 * Determine whether the given object is empty. 110 * <p>This method supports the following object types. 111 * <ul> 112 * <li>{@code Array}: considered empty if its length is zero</li> 113 * <li>{@link CharSequence}: considered empty if its length is zero</li> 114 * <li>{@link Collection}: delegates to {@link Collection#isEmpty()}</li> 115 * <li>{@link Map}: delegates to {@link Map#isEmpty()}</li> 116 * </ul> 117 * <p>If the given object is non-null and not one of the aforementioned 118 * supported types, this method returns {@code false}. 119 * @param obj the object to check 120 * @return {@code true} if the object is {@code null} or <em>empty</em> 121 * @since 4.2 122 * @see ObjectUtils#isEmpty(Object[]) 123 * @see StringUtils#hasLength(CharSequence) 124 * @see StringUtils#isEmpty(Object) 125 * @see CollectionUtils#isEmpty(java.util.Collection) 126 * @see CollectionUtils#isEmpty(java.util.Map) 127 */ 128 @SuppressWarnings("rawtypes") 129 public static boolean isEmpty(Object obj) { 130 if (obj == null) { 131 return true; 132 } 133 134 if (obj instanceof CharSequence) { 135 return ((CharSequence) obj).length() == 0; 136 } 137 if (obj.getClass().isArray()) { 138 return Array.getLength(obj) == 0; 139 } 140 if (obj instanceof Collection) { 141 return ((Collection) obj).isEmpty(); 142 } 143 if (obj instanceof Map) { 144 return ((Map) obj).isEmpty(); 145 } 146 147 // else 148 return false; 149 } 150 151 /** 152 * Check whether the given array contains the given element. 153 * @param array the array to check (may be {@code null}, 154 * in which case the return value will always be {@code false}) 155 * @param element the element to check for 156 * @return whether the element has been found in the given array 157 */ 158 public static boolean containsElement(Object[] array, Object element) { 159 if (array == null) { 160 return false; 161 } 162 for (Object arrayEle : array) { 163 if (nullSafeEquals(arrayEle, element)) { 164 return true; 165 } 166 } 167 return false; 168 } 169 170 /** 171 * Check whether the given array of enum constants contains a constant with the given name, 172 * ignoring case when determining a match. 173 * @param enumValues the enum values to check, typically obtained via {@code MyEnum.values()} 174 * @param constant the constant name to find (must not be null or empty string) 175 * @return whether the constant has been found in the given array 176 */ 177 public static boolean containsConstant(Enum<?>[] enumValues, String constant) { 178 return containsConstant(enumValues, constant, false); 179 } 180 181 /** 182 * Check whether the given array of enum constants contains a constant with the given name. 183 * @param enumValues the enum values to check, typically obtained via {@code MyEnum.values()} 184 * @param constant the constant name to find (must not be null or empty string) 185 * @param caseSensitive whether case is significant in determining a match 186 * @return whether the constant has been found in the given array 187 */ 188 public static boolean containsConstant(Enum<?>[] enumValues, String constant, boolean caseSensitive) { 189 for (Enum<?> candidate : enumValues) { 190 if (caseSensitive ? candidate.toString().equals(constant) : 191 candidate.toString().equalsIgnoreCase(constant)) { 192 return true; 193 } 194 } 195 return false; 196 } 197 198 /** 199 * Case insensitive alternative to {@link Enum#valueOf(Class, String)}. 200 * @param <E> the concrete Enum type 201 * @param enumValues the array of all Enum constants in question, usually per {@code Enum.values()} 202 * @param constant the constant to get the enum value of 203 * @throws IllegalArgumentException if the given constant is not found in the given array 204 * of enum values. Use {@link #containsConstant(Enum[], String)} as a guard to avoid this exception. 205 */ 206 public static <E extends Enum<?>> E caseInsensitiveValueOf(E[] enumValues, String constant) { 207 for (E candidate : enumValues) { 208 if (candidate.toString().equalsIgnoreCase(constant)) { 209 return candidate; 210 } 211 } 212 throw new IllegalArgumentException("Constant [" + constant + "] does not exist in enum type " + 213 enumValues.getClass().getComponentType().getName()); 214 } 215 216 /** 217 * Append the given object to the given array, returning a new array 218 * consisting of the input array contents plus the given object. 219 * @param array the array to append to (can be {@code null}) 220 * @param obj the object to append 221 * @return the new array (of the same component type; never {@code null}) 222 */ 223 public static <A, O extends A> A[] addObjectToArray(A[] array, O obj) { 224 Class<?> compType = Object.class; 225 if (array != null) { 226 compType = array.getClass().getComponentType(); 227 } 228 else if (obj != null) { 229 compType = obj.getClass(); 230 } 231 int newArrLength = (array != null ? array.length + 1 : 1); 232 @SuppressWarnings("unchecked") 233 A[] newArr = (A[]) Array.newInstance(compType, newArrLength); 234 if (array != null) { 235 System.arraycopy(array, 0, newArr, 0, array.length); 236 } 237 newArr[newArr.length - 1] = obj; 238 return newArr; 239 } 240 241 /** 242 * Convert the given array (which may be a primitive array) to an 243 * object array (if necessary of primitive wrapper objects). 244 * <p>A {@code null} source value will be converted to an 245 * empty Object array. 246 * @param source the (potentially primitive) array 247 * @return the corresponding object array (never {@code null}) 248 * @throws IllegalArgumentException if the parameter is not an array 249 */ 250 public static Object[] toObjectArray(Object source) { 251 if (source instanceof Object[]) { 252 return (Object[]) source; 253 } 254 if (source == null) { 255 return new Object[0]; 256 } 257 if (!source.getClass().isArray()) { 258 throw new IllegalArgumentException("Source is not an array: " + source); 259 } 260 int length = Array.getLength(source); 261 if (length == 0) { 262 return new Object[0]; 263 } 264 Class<?> wrapperType = Array.get(source, 0).getClass(); 265 Object[] newArray = (Object[]) Array.newInstance(wrapperType, length); 266 for (int i = 0; i < length; i++) { 267 newArray[i] = Array.get(source, i); 268 } 269 return newArray; 270 } 271 272 273 //--------------------------------------------------------------------- 274 // Convenience methods for content-based equality/hash-code handling 275 //--------------------------------------------------------------------- 276 277 /** 278 * Determine if the given objects are equal, returning {@code true} if 279 * both are {@code null} or {@code false} if only one is {@code null}. 280 * <p>Compares arrays with {@code Arrays.equals}, performing an equality 281 * check based on the array elements rather than the array reference. 282 * @param o1 first Object to compare 283 * @param o2 second Object to compare 284 * @return whether the given objects are equal 285 * @see Object#equals(Object) 286 * @see java.util.Arrays#equals 287 */ 288 public static boolean nullSafeEquals(Object o1, Object o2) { 289 if (o1 == o2) { 290 return true; 291 } 292 if (o1 == null || o2 == null) { 293 return false; 294 } 295 if (o1.equals(o2)) { 296 return true; 297 } 298 if (o1.getClass().isArray() && o2.getClass().isArray()) { 299 return arrayEquals(o1, o2); 300 } 301 return false; 302 } 303 304 /** 305 * Compare the given arrays with {@code Arrays.equals}, performing an equality 306 * check based on the array elements rather than the array reference. 307 * @param o1 first array to compare 308 * @param o2 second array to compare 309 * @return whether the given objects are equal 310 * @see #nullSafeEquals(Object, Object) 311 * @see java.util.Arrays#equals 312 */ 313 private static boolean arrayEquals(Object o1, Object o2) { 314 if (o1 instanceof Object[] && o2 instanceof Object[]) { 315 return Arrays.equals((Object[]) o1, (Object[]) o2); 316 } 317 if (o1 instanceof boolean[] && o2 instanceof boolean[]) { 318 return Arrays.equals((boolean[]) o1, (boolean[]) o2); 319 } 320 if (o1 instanceof byte[] && o2 instanceof byte[]) { 321 return Arrays.equals((byte[]) o1, (byte[]) o2); 322 } 323 if (o1 instanceof char[] && o2 instanceof char[]) { 324 return Arrays.equals((char[]) o1, (char[]) o2); 325 } 326 if (o1 instanceof double[] && o2 instanceof double[]) { 327 return Arrays.equals((double[]) o1, (double[]) o2); 328 } 329 if (o1 instanceof float[] && o2 instanceof float[]) { 330 return Arrays.equals((float[]) o1, (float[]) o2); 331 } 332 if (o1 instanceof int[] && o2 instanceof int[]) { 333 return Arrays.equals((int[]) o1, (int[]) o2); 334 } 335 if (o1 instanceof long[] && o2 instanceof long[]) { 336 return Arrays.equals((long[]) o1, (long[]) o2); 337 } 338 if (o1 instanceof short[] && o2 instanceof short[]) { 339 return Arrays.equals((short[]) o1, (short[]) o2); 340 } 341 return false; 342 } 343 344 /** 345 * Return as hash code for the given object; typically the value of 346 * {@code Object#hashCode()}}. If the object is an array, 347 * this method will delegate to any of the {@code nullSafeHashCode} 348 * methods for arrays in this class. If the object is {@code null}, 349 * this method returns 0. 350 * @see Object#hashCode() 351 * @see #nullSafeHashCode(Object[]) 352 * @see #nullSafeHashCode(boolean[]) 353 * @see #nullSafeHashCode(byte[]) 354 * @see #nullSafeHashCode(char[]) 355 * @see #nullSafeHashCode(double[]) 356 * @see #nullSafeHashCode(float[]) 357 * @see #nullSafeHashCode(int[]) 358 * @see #nullSafeHashCode(long[]) 359 * @see #nullSafeHashCode(short[]) 360 */ 361 public static int nullSafeHashCode(Object obj) { 362 if (obj == null) { 363 return 0; 364 } 365 if (obj.getClass().isArray()) { 366 if (obj instanceof Object[]) { 367 return nullSafeHashCode((Object[]) obj); 368 } 369 if (obj instanceof boolean[]) { 370 return nullSafeHashCode((boolean[]) obj); 371 } 372 if (obj instanceof byte[]) { 373 return nullSafeHashCode((byte[]) obj); 374 } 375 if (obj instanceof char[]) { 376 return nullSafeHashCode((char[]) obj); 377 } 378 if (obj instanceof double[]) { 379 return nullSafeHashCode((double[]) obj); 380 } 381 if (obj instanceof float[]) { 382 return nullSafeHashCode((float[]) obj); 383 } 384 if (obj instanceof int[]) { 385 return nullSafeHashCode((int[]) obj); 386 } 387 if (obj instanceof long[]) { 388 return nullSafeHashCode((long[]) obj); 389 } 390 if (obj instanceof short[]) { 391 return nullSafeHashCode((short[]) obj); 392 } 393 } 394 return obj.hashCode(); 395 } 396 397 /** 398 * Return a hash code based on the contents of the specified array. 399 * If {@code array} is {@code null}, this method returns 0. 400 */ 401 public static int nullSafeHashCode(Object[] array) { 402 if (array == null) { 403 return 0; 404 } 405 int hash = INITIAL_HASH; 406 for (Object element : array) { 407 hash = MULTIPLIER * hash + nullSafeHashCode(element); 408 } 409 return hash; 410 } 411 412 /** 413 * Return a hash code based on the contents of the specified array. 414 * If {@code array} is {@code null}, this method returns 0. 415 */ 416 public static int nullSafeHashCode(boolean[] array) { 417 if (array == null) { 418 return 0; 419 } 420 int hash = INITIAL_HASH; 421 for (boolean element : array) { 422 hash = MULTIPLIER * hash + hashCode(element); 423 } 424 return hash; 425 } 426 427 /** 428 * Return a hash code based on the contents of the specified array. 429 * If {@code array} is {@code null}, this method returns 0. 430 */ 431 public static int nullSafeHashCode(byte[] array) { 432 if (array == null) { 433 return 0; 434 } 435 int hash = INITIAL_HASH; 436 for (byte element : array) { 437 hash = MULTIPLIER * hash + element; 438 } 439 return hash; 440 } 441 442 /** 443 * Return a hash code based on the contents of the specified array. 444 * If {@code array} is {@code null}, this method returns 0. 445 */ 446 public static int nullSafeHashCode(char[] array) { 447 if (array == null) { 448 return 0; 449 } 450 int hash = INITIAL_HASH; 451 for (char element : array) { 452 hash = MULTIPLIER * hash + element; 453 } 454 return hash; 455 } 456 457 /** 458 * Return a hash code based on the contents of the specified array. 459 * If {@code array} is {@code null}, this method returns 0. 460 */ 461 public static int nullSafeHashCode(double[] array) { 462 if (array == null) { 463 return 0; 464 } 465 int hash = INITIAL_HASH; 466 for (double element : array) { 467 hash = MULTIPLIER * hash + hashCode(element); 468 } 469 return hash; 470 } 471 472 /** 473 * Return a hash code based on the contents of the specified array. 474 * If {@code array} is {@code null}, this method returns 0. 475 */ 476 public static int nullSafeHashCode(float[] array) { 477 if (array == null) { 478 return 0; 479 } 480 int hash = INITIAL_HASH; 481 for (float element : array) { 482 hash = MULTIPLIER * hash + hashCode(element); 483 } 484 return hash; 485 } 486 487 /** 488 * Return a hash code based on the contents of the specified array. 489 * If {@code array} is {@code null}, this method returns 0. 490 */ 491 public static int nullSafeHashCode(int[] array) { 492 if (array == null) { 493 return 0; 494 } 495 int hash = INITIAL_HASH; 496 for (int element : array) { 497 hash = MULTIPLIER * hash + element; 498 } 499 return hash; 500 } 501 502 /** 503 * Return a hash code based on the contents of the specified array. 504 * If {@code array} is {@code null}, this method returns 0. 505 */ 506 public static int nullSafeHashCode(long[] array) { 507 if (array == null) { 508 return 0; 509 } 510 int hash = INITIAL_HASH; 511 for (long element : array) { 512 hash = MULTIPLIER * hash + hashCode(element); 513 } 514 return hash; 515 } 516 517 /** 518 * Return a hash code based on the contents of the specified array. 519 * If {@code array} is {@code null}, this method returns 0. 520 */ 521 public static int nullSafeHashCode(short[] array) { 522 if (array == null) { 523 return 0; 524 } 525 int hash = INITIAL_HASH; 526 for (short element : array) { 527 hash = MULTIPLIER * hash + element; 528 } 529 return hash; 530 } 531 532 /** 533 * Return the same value as {@link Boolean#hashCode()}}. 534 * @see Boolean#hashCode() 535 */ 536 public static int hashCode(boolean bool) { 537 return (bool ? 1231 : 1237); 538 } 539 540 /** 541 * Return the same value as {@link Double#hashCode()}}. 542 * @see Double#hashCode() 543 */ 544 public static int hashCode(double dbl) { 545 return hashCode(Double.doubleToLongBits(dbl)); 546 } 547 548 /** 549 * Return the same value as {@link Float#hashCode()}}. 550 * @see Float#hashCode() 551 */ 552 public static int hashCode(float flt) { 553 return Float.floatToIntBits(flt); 554 } 555 556 /** 557 * Return the same value as {@link Long#hashCode()}}. 558 * @see Long#hashCode() 559 */ 560 public static int hashCode(long lng) { 561 return (int) (lng ^ (lng >>> 32)); 562 } 563 564 565 //--------------------------------------------------------------------- 566 // Convenience methods for toString output 567 //--------------------------------------------------------------------- 568 569 /** 570 * Return a String representation of an object's overall identity. 571 * @param obj the object (may be {@code null}) 572 * @return the object's identity as String representation, 573 * or an empty String if the object was {@code null} 574 */ 575 public static String identityToString(Object obj) { 576 if (obj == null) { 577 return EMPTY_STRING; 578 } 579 return obj.getClass().getName() + "@" + getIdentityHexString(obj); 580 } 581 582 /** 583 * Return a hex String form of an object's identity hash code. 584 * @param obj the object 585 * @return the object's identity code in hex notation 586 */ 587 public static String getIdentityHexString(Object obj) { 588 return Integer.toHexString(System.identityHashCode(obj)); 589 } 590 591 /** 592 * Return a content-based String representation if {@code obj} is 593 * not {@code null}; otherwise returns an empty String. 594 * <p>Differs from {@link #nullSafeToString(Object)} in that it returns 595 * an empty String rather than "null" for a {@code null} value. 596 * @param obj the object to build a display String for 597 * @return a display String representation of {@code obj} 598 * @see #nullSafeToString(Object) 599 */ 600 public static String getDisplayString(Object obj) { 601 if (obj == null) { 602 return EMPTY_STRING; 603 } 604 return nullSafeToString(obj); 605 } 606 607 /** 608 * Determine the class name for the given object. 609 * <p>Returns a {@code "null"} String if {@code obj} is {@code null}. 610 * @param obj the object to introspect (may be {@code null}) 611 * @return the corresponding class name 612 */ 613 public static String nullSafeClassName(Object obj) { 614 return (obj != null ? obj.getClass().getName() : NULL_STRING); 615 } 616 617 /** 618 * Return a String representation of the specified Object. 619 * <p>Builds a String representation of the contents in case of an array. 620 * Returns a {@code "null"} String if {@code obj} is {@code null}. 621 * @param obj the object to build a String representation for 622 * @return a String representation of {@code obj} 623 */ 624 public static String nullSafeToString(Object obj) { 625 if (obj == null) { 626 return NULL_STRING; 627 } 628 if (obj instanceof String) { 629 return (String) obj; 630 } 631 if (obj instanceof Object[]) { 632 return nullSafeToString((Object[]) obj); 633 } 634 if (obj instanceof boolean[]) { 635 return nullSafeToString((boolean[]) obj); 636 } 637 if (obj instanceof byte[]) { 638 return nullSafeToString((byte[]) obj); 639 } 640 if (obj instanceof char[]) { 641 return nullSafeToString((char[]) obj); 642 } 643 if (obj instanceof double[]) { 644 return nullSafeToString((double[]) obj); 645 } 646 if (obj instanceof float[]) { 647 return nullSafeToString((float[]) obj); 648 } 649 if (obj instanceof int[]) { 650 return nullSafeToString((int[]) obj); 651 } 652 if (obj instanceof long[]) { 653 return nullSafeToString((long[]) obj); 654 } 655 if (obj instanceof short[]) { 656 return nullSafeToString((short[]) obj); 657 } 658 String str = obj.toString(); 659 return (str != null ? str : EMPTY_STRING); 660 } 661 662 /** 663 * Return a String representation of the contents of the specified array. 664 * <p>The String representation consists of a list of the array's elements, 665 * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated 666 * by the characters {@code ", "} (a comma followed by a space). 667 * Returns a {@code "null"} String if {@code array} is {@code null}. 668 * @param array the array to build a String representation for 669 * @return a String representation of {@code array} 670 */ 671 public static String nullSafeToString(Object[] array) { 672 if (array == null) { 673 return NULL_STRING; 674 } 675 int length = array.length; 676 if (length == 0) { 677 return EMPTY_ARRAY; 678 } 679 StringBuilder sb = new StringBuilder(); 680 for (int i = 0; i < length; i++) { 681 if (i == 0) { 682 sb.append(ARRAY_START); 683 } 684 else { 685 sb.append(ARRAY_ELEMENT_SEPARATOR); 686 } 687 sb.append(String.valueOf(array[i])); 688 } 689 sb.append(ARRAY_END); 690 return sb.toString(); 691 } 692 693 /** 694 * Return a String representation of the contents of the specified array. 695 * <p>The String representation consists of a list of the array's elements, 696 * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated 697 * by the characters {@code ", "} (a comma followed by a space). 698 * Returns a {@code "null"} String if {@code array} is {@code null}. 699 * @param array the array to build a String representation for 700 * @return a String representation of {@code array} 701 */ 702 public static String nullSafeToString(boolean[] array) { 703 if (array == null) { 704 return NULL_STRING; 705 } 706 int length = array.length; 707 if (length == 0) { 708 return EMPTY_ARRAY; 709 } 710 StringBuilder sb = new StringBuilder(); 711 for (int i = 0; i < length; i++) { 712 if (i == 0) { 713 sb.append(ARRAY_START); 714 } 715 else { 716 sb.append(ARRAY_ELEMENT_SEPARATOR); 717 } 718 719 sb.append(array[i]); 720 } 721 sb.append(ARRAY_END); 722 return sb.toString(); 723 } 724 725 /** 726 * Return a String representation of the contents of the specified array. 727 * <p>The String representation consists of a list of the array's elements, 728 * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated 729 * by the characters {@code ", "} (a comma followed by a space). 730 * Returns a {@code "null"} String if {@code array} is {@code null}. 731 * @param array the array to build a String representation for 732 * @return a String representation of {@code array} 733 */ 734 public static String nullSafeToString(byte[] array) { 735 if (array == null) { 736 return NULL_STRING; 737 } 738 int length = array.length; 739 if (length == 0) { 740 return EMPTY_ARRAY; 741 } 742 StringBuilder sb = new StringBuilder(); 743 for (int i = 0; i < length; i++) { 744 if (i == 0) { 745 sb.append(ARRAY_START); 746 } 747 else { 748 sb.append(ARRAY_ELEMENT_SEPARATOR); 749 } 750 sb.append(array[i]); 751 } 752 sb.append(ARRAY_END); 753 return sb.toString(); 754 } 755 756 /** 757 * Return a String representation of the contents of the specified array. 758 * <p>The String representation consists of a list of the array's elements, 759 * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated 760 * by the characters {@code ", "} (a comma followed by a space). 761 * Returns a {@code "null"} String if {@code array} is {@code null}. 762 * @param array the array to build a String representation for 763 * @return a String representation of {@code array} 764 */ 765 public static String nullSafeToString(char[] array) { 766 if (array == null) { 767 return NULL_STRING; 768 } 769 int length = array.length; 770 if (length == 0) { 771 return EMPTY_ARRAY; 772 } 773 StringBuilder sb = new StringBuilder(); 774 for (int i = 0; i < length; i++) { 775 if (i == 0) { 776 sb.append(ARRAY_START); 777 } 778 else { 779 sb.append(ARRAY_ELEMENT_SEPARATOR); 780 } 781 sb.append("'").append(array[i]).append("'"); 782 } 783 sb.append(ARRAY_END); 784 return sb.toString(); 785 } 786 787 /** 788 * Return a String representation of the contents of the specified array. 789 * <p>The String representation consists of a list of the array's elements, 790 * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated 791 * by the characters {@code ", "} (a comma followed by a space). 792 * Returns a {@code "null"} String if {@code array} is {@code null}. 793 * @param array the array to build a String representation for 794 * @return a String representation of {@code array} 795 */ 796 public static String nullSafeToString(double[] array) { 797 if (array == null) { 798 return NULL_STRING; 799 } 800 int length = array.length; 801 if (length == 0) { 802 return EMPTY_ARRAY; 803 } 804 StringBuilder sb = new StringBuilder(); 805 for (int i = 0; i < length; i++) { 806 if (i == 0) { 807 sb.append(ARRAY_START); 808 } 809 else { 810 sb.append(ARRAY_ELEMENT_SEPARATOR); 811 } 812 813 sb.append(array[i]); 814 } 815 sb.append(ARRAY_END); 816 return sb.toString(); 817 } 818 819 /** 820 * Return a String representation of the contents of the specified array. 821 * <p>The String representation consists of a list of the array's elements, 822 * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated 823 * by the characters {@code ", "} (a comma followed by a space). 824 * Returns a {@code "null"} String if {@code array} is {@code null}. 825 * @param array the array to build a String representation for 826 * @return a String representation of {@code array} 827 */ 828 public static String nullSafeToString(float[] array) { 829 if (array == null) { 830 return NULL_STRING; 831 } 832 int length = array.length; 833 if (length == 0) { 834 return EMPTY_ARRAY; 835 } 836 StringBuilder sb = new StringBuilder(); 837 for (int i = 0; i < length; i++) { 838 if (i == 0) { 839 sb.append(ARRAY_START); 840 } 841 else { 842 sb.append(ARRAY_ELEMENT_SEPARATOR); 843 } 844 845 sb.append(array[i]); 846 } 847 sb.append(ARRAY_END); 848 return sb.toString(); 849 } 850 851 /** 852 * Return a String representation of the contents of the specified array. 853 * <p>The String representation consists of a list of the array's elements, 854 * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated 855 * by the characters {@code ", "} (a comma followed by a space). 856 * Returns a {@code "null"} String if {@code array} is {@code null}. 857 * @param array the array to build a String representation for 858 * @return a String representation of {@code array} 859 */ 860 public static String nullSafeToString(int[] array) { 861 if (array == null) { 862 return NULL_STRING; 863 } 864 int length = array.length; 865 if (length == 0) { 866 return EMPTY_ARRAY; 867 } 868 StringBuilder sb = new StringBuilder(); 869 for (int i = 0; i < length; i++) { 870 if (i == 0) { 871 sb.append(ARRAY_START); 872 } 873 else { 874 sb.append(ARRAY_ELEMENT_SEPARATOR); 875 } 876 sb.append(array[i]); 877 } 878 sb.append(ARRAY_END); 879 return sb.toString(); 880 } 881 882 /** 883 * Return a String representation of the contents of the specified array. 884 * <p>The String representation consists of a list of the array's elements, 885 * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated 886 * by the characters {@code ", "} (a comma followed by a space). 887 * Returns a {@code "null"} String if {@code array} is {@code null}. 888 * @param array the array to build a String representation for 889 * @return a String representation of {@code array} 890 */ 891 public static String nullSafeToString(long[] array) { 892 if (array == null) { 893 return NULL_STRING; 894 } 895 int length = array.length; 896 if (length == 0) { 897 return EMPTY_ARRAY; 898 } 899 StringBuilder sb = new StringBuilder(); 900 for (int i = 0; i < length; i++) { 901 if (i == 0) { 902 sb.append(ARRAY_START); 903 } 904 else { 905 sb.append(ARRAY_ELEMENT_SEPARATOR); 906 } 907 sb.append(array[i]); 908 } 909 sb.append(ARRAY_END); 910 return sb.toString(); 911 } 912 913 /** 914 * Return a String representation of the contents of the specified array. 915 * <p>The String representation consists of a list of the array's elements, 916 * enclosed in curly braces ({@code "{}"}). Adjacent elements are separated 917 * by the characters {@code ", "} (a comma followed by a space). 918 * Returns a {@code "null"} String if {@code array} is {@code null}. 919 * @param array the array to build a String representation for 920 * @return a String representation of {@code array} 921 */ 922 public static String nullSafeToString(short[] array) { 923 if (array == null) { 924 return NULL_STRING; 925 } 926 int length = array.length; 927 if (length == 0) { 928 return EMPTY_ARRAY; 929 } 930 StringBuilder sb = new StringBuilder(); 931 for (int i = 0; i < length; i++) { 932 if (i == 0) { 933 sb.append(ARRAY_START); 934 } 935 else { 936 sb.append(ARRAY_ELEMENT_SEPARATOR); 937 } 938 sb.append(array[i]); 939 } 940 sb.append(ARRAY_END); 941 return sb.toString(); 942 } 943 944}